diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000000..185873ad02a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,33 @@ +name: Bug Report +description: Create a report to help us improve +title: "[BUG] - Issue Title" +labels: bug + +body: + - type: markdown + attributes: + value: "## Describe the bug\nA clear and concise description of what the bug is." + + - type: textarea + attributes: + label: Steps to Reproduce + description: "List the steps to reproduce the bug." + placeholder: "1. Go to '...'\n2. Click on '...'\n3. See error" + + - type: textarea + attributes: + label: Expected Behavior + description: "Describe the behavior you expected to see." + placeholder: "A clear and concise description of what you expected to happen." + + - type: input + attributes: + label: Servicecomb Version + description: "Please provide your Servicecomb version" + placeholder: "3.2.4" + + - type: textarea + attributes: + label: Additional Context + description: "Add any other context about the problem here." + placeholder: "Any additional information that might help us debug the issue." diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000000..16fd2512ea7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,18 @@ +blank_issues_enabled: false +contact_links: + - name: "Contact Support" + url: "mailto:dev@servicecomb.apache.org" + about: "If you need help, please contact us." +templates: + - name: "Bug Report" + description: "Report a bug or issue." + filename: "bug_report.yml" + - name: "Feature Request" + description: "Request a new feature or improvement." + filename: "feature_request.yml" + - name: "Documentation Issue" + description: "Report an issue with documentation." + filename: "documentation_issue.yml" + - name: "Question" + description: "Ask a question or seek help." + filename: "question.yml" diff --git a/.github/ISSUE_TEMPLATE/documentation_issue.yml b/.github/ISSUE_TEMPLATE/documentation_issue.yml new file mode 100644 index 00000000000..94ef3490041 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation_issue.yml @@ -0,0 +1,27 @@ +name: Documentation Issue +description: Report an issue with the documentation +title: "[DOCUMENTATION] - Documentation Issue Title" +labels: documentation + +body: + - type: markdown + attributes: + value: "## Describe the documentation issue\nA clear and concise description of the issue with the documentation." + + - type: textarea + attributes: + label: Location in documentation + description: "Please provide the URL or section where the issue appears." + placeholder: "e.g. https://docs.example.com/section" + + - type: textarea + attributes: + label: What should be changed? + description: "Please describe what changes or improvements should be made to the documentation." + placeholder: "Explain how we can improve the content." + + - type: textarea + attributes: + label: Additional Context + description: "Provide any other context or examples here." + placeholder: "Additional comments or suggestions for the documentation." diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000000..3a44565e0b2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,33 @@ +name: Feature Request +description: Suggest an idea or feature for this project +title: "[FEATURE] - Feature Title" +labels: enhancement + +body: + - type: markdown + attributes: + value: "## Describe the feature request\nA clear and concise description of what you want to be added to the project." + + - type: textarea + attributes: + label: Problem this feature would solve + description: "Please describe the problem or challenge you're facing." + placeholder: "Explain why this feature would be helpful." + + - type: textarea + attributes: + label: Describe the solution + description: "How do you envision this feature working?" + placeholder: "Provide a description of how the feature would solve the problem." + + - type: textarea + attributes: + label: Alternatives considered + description: "Have you considered other solutions or alternatives? If yes, describe them." + placeholder: "Provide any alternative solutions you've thought about." + + - type: textarea + attributes: + label: Additional Context + description: "Any other context or information that might help us implement this feature." + placeholder: "Include any links, mockups, or additional details." diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml new file mode 100644 index 00000000000..af3f350b518 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -0,0 +1,27 @@ +name: General Question +description: Ask a general question related to the project +title: "[QUESTION] - Question Title" +labels: question + +body: + - type: markdown + attributes: + value: "## What is your question?\nDescribe the question or issue you are facing. Be as specific as possible." + + - type: textarea + attributes: + label: Steps to reproduce (if applicable) + description: "If your question is about a specific problem or bug, please include steps to reproduce it." + placeholder: "Provide steps, if applicable." + + - type: textarea + attributes: + label: What have you tried so far? + description: "Please explain what you have already tried to resolve the issue or answer the question." + placeholder: "Describe the steps you've taken." + + - type: textarea + attributes: + label: Additional context + description: "Provide any other context or information related to the question." + placeholder: "Include any relevant links or background information." diff --git a/.github/workflows/checkstyle.yml b/.github/workflows/checkstyle.yml index 9b153e77a3e..3f97b9f1818 100644 --- a/.github/workflows/checkstyle.yml +++ b/.github/workflows/checkstyle.yml @@ -26,13 +26,13 @@ on: jobs: checkstyle: timeout-minutes: 60 - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up jdk - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: java-version: '17' distribution: 'temurin' - name: checkstyle - run: mvn -B -Pit install -DskipTests -Dspotbugs.skip=true checkstyle:check + run: mvn checkstyle:check -B -Pit diff --git a/.github/workflows/linelint.yml b/.github/workflows/linelint.yml index 6f6ae1180e9..8d5112ea3d6 100644 --- a/.github/workflows/linelint.yml +++ b/.github/workflows/linelint.yml @@ -26,9 +26,9 @@ on: jobs: linelint: timeout-minutes: 60 - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: install linelint run: cargo install linelint-cli - name: Run linelint check diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 7b2ef9f23d5..24118c35c99 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -29,22 +29,24 @@ jobs: build: timeout-minutes: 60 - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up jdk - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: - java-version: '17' + java-version: '17.0.8' distribution: 'temurin' - - uses: actions/cache@v4 + - name: Set up Maven + uses: stCarolas/setup-maven@v5 + with: + maven-version: 3.9.9 + - uses: actions/cache@v5 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-maven- - name: Compilation and Installation - run: mvn clean install -Dcheckstyle.skip -Dspotbugs.skip=true -B -Pdocker -Pjacoco -Pit -Pcoverage - - name: publish coverage report - run: bash <(curl -s https://codecov.io/bash) + run: mvn clean verify -Dcheckstyle.skip=true -B -Pdocker -Pjacoco -Pit -Pcoverage diff --git a/.github/workflows/rat_check.yml b/.github/workflows/rat_check.yml index b1d8c55532b..c2db2508fea 100644 --- a/.github/workflows/rat_check.yml +++ b/.github/workflows/rat_check.yml @@ -29,11 +29,11 @@ on: jobs: rat_check: timeout-minutes: 60 - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up jdk - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/spotbugs.yml b/.github/workflows/spotbugs.yml deleted file mode 100644 index 0d66fdbe31c..00000000000 --- a/.github/workflows/spotbugs.yml +++ /dev/null @@ -1,38 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -name: spot bugs -on: - pull_request: - branches: - - master - -jobs: - spotbugs: - timeout-minutes: 60 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up jdk - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'temurin' - - name: spotbugs - run: mvn -B -Pit -DskipTests clean verify spotbugs:spotbugs diff --git a/.github/workflows/typo_check.yml b/.github/workflows/typo_check.yml index 9fe9d2fcd78..999530a79f7 100644 --- a/.github/workflows/typo_check.yml +++ b/.github/workflows/typo_check.yml @@ -26,13 +26,13 @@ on: jobs: typo-check: timeout-minutes: 60 - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 # To run the typo check locally, you can follow these steps: # 1. Install typos locally using cargo: # cargo install typos-cli # 2. Run the typo check with the following command: # typos - name: Check typos - uses: crate-ci/typos@master + uses: crate-ci/typos@v1.38.1 diff --git a/NOTICE b/NOTICE index 5ed927047d5..e4df59ae99a 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ Apache ServiceComb Java Chassis -Copyright 2017-2024 The Apache Software Foundation +Copyright 2017-2025 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). diff --git a/README.md b/README.md index 73bda88b94a..b2fbc167625 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,27 @@ Apache 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. +> If you find this project helpful, please don't forget to `star` it. + # releases | Release Train | Latest Version | Compiled JDK Version | Tested JDK Version | Open API | Notes | |----------------|----------------|----------------------|--------------------|----------|--------------------------| -| Java Chassis 3 | 3.2.2 | OpenJDK 17 | OpenJDK 17 | 3.0.x | Depends on Spring Boot 3 | -| Java Chassis 2 | 2.8.20 | OpenJDK 8 | OpenJDK 8, 11, 17 | 2.0.x | Depends on Spring 5 | +| Java Chassis 3 | 3.3.0 | OpenJDK 17 | OpenJDK 17 | 3.0.x | Depends on Spring Boot 3 | +| Java Chassis 2 | 2.8.24 | OpenJDK 8 | OpenJDK 8, 11, 17 | 2.0.x | Depends on Spring 5 | | Java Chassis 1 | 1.3.11 | OpenJDK 8 | OpenJDK 8 | 2.0.x | End of Support | ->>>NOTICE: Since Open API 3.0.x is not compatible with 2.0.x, Java Chassis 2 and Java Chassis 1 can not +Java Chassis core dependencies + +| Java Chassis | Spring Boot | Vert.x | Swagger | Jackson | +|--------------|-------------|--------|---------|---------| +| 3.3.x | 3.4.x | 4.5.x | 2.2.x | 2.18.x | +| 3.2.x | 3.3.x | 4.5.x | 2.2.x | 2.18.x | + +> NOTICE: Since Open API 3.0.x is not compatible with 2.0.x, Java Chassis 2 and Java Chassis 1 can not > work together with Java Chassis 3. All related consumers, providers and edge service need use Java Chassis 3 when upgrading. ->>>NOTICE: Java Chassis 1 reached its end of support now after it's first release from 2018. +> NOTICE: Java Chassis 1 reached its end of support now after it's first release from 2018. # Quick Start @@ -103,11 +112,5 @@ mailing list: [subscribe](mailto:dev-subscribe@servicecomb.apache.org) [dev](ht See [CONTRIBUTING](http://servicecomb.apache.org/developers/contributing) for details on submitting patches and the contribution workflow. -# Star this project - -If you like this project, do not forget star it. - -[![Star History Chart](https://api.star-history.com/svg?repos=apache/servicecomb-java-chassis&type=Date)](https://star-history.com/#apache/servicecomb-java-chassis&Date) - # License Licensed under an [Apache 2.0 license](LICENSE). diff --git a/README_ZH.md b/README_ZH.md index 7f378a96a6f..bfae9746c2b 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -10,17 +10,26 @@ Apache ServiceComb Java Chassis 给开发者提供一个快速构建微服务的 可以通过[设计选型参考](https://servicecomb.apache.org/references/java-chassis/zh_CN/start/design.html) 了解更多特性和设计原理。 +> 如果发现项目能帮助到您,别忘了点击右上角`star`表示鼓励。 + # 发布版本 | 版本火车 | 最新版本 | 编译的JDK版本 | 支持的JDK版本 | Open API | 备注 | |----------------|--------|------------|-------------------|----------|-----------------| -| Java Chassis 3 | 3.2.2 | OpenJDK 17 | OpenJDK 17 | 3.0.x | 依赖Spring Boot 3 | -| Java Chassis 2 | 2.8.20 | OpenJDK 8 | OpenJDK 8, 11, 17 | 2.0.x | 依赖Spring 5 | +| Java Chassis 3 | 3.3.0 | OpenJDK 17 | OpenJDK 17 | 3.0.x | 依赖Spring Boot 3 | +| Java Chassis 2 | 2.8.24 | OpenJDK 8 | OpenJDK 8, 11, 17 | 2.0.x | 依赖Spring 5 | | Java Chassis 1 | 1.3.11 | OpenJDK 8 | OpenJDK 8 | 2.0.x | 停止更新 | ->>>NOTICE: Open API 3.0.x 不兼容 2.0.x, 因此Java Chassis 2、Java Chassis 1不能与Java Chassis 3共存互访. 升级Java Chassis 3, 需要将相关的消费者、提供者和边缘服务同时升级. +Java Chassis 的核心依赖 + +| Java Chassis | Spring Boot | Vert.x | Swagger | Jackson | +|--------------|-------------|--------|---------|---------| +| 3.3.x | 3.4.x | 4.5.x | 2.2.x | 2.18.x | +| 3.2.x | 3.3.x | 4.5.x | 2.2.x | 2.18.x | + +> NOTICE: Open API 3.0.x 不兼容 2.0.x, 因此Java Chassis 2、Java Chassis 1不能与Java Chassis 3共存互访. 升级Java Chassis 3, 需要将相关的消费者、提供者和边缘服务同时升级. ->>>NOTICE: Java Chassis 1 第一个版本于2018发布,已经停止更新. +> NOTICE: Java Chassis 1 第一个版本于2018发布,已经停止更新. # 快速开始 @@ -111,11 +120,5 @@ public class ConsumerController implements ConsumerService { 参考 [如何做贡献](http://servicecomb.apache.org/cn/developers/contributing). -# 给项目加星 - -如果喜欢这个项目,请给项目加星,把它推荐给更多人。 - -[![Star History Chart](https://api.star-history.com/svg?repos=apache/servicecomb-java-chassis&type=Date)](https://star-history.com/#apache/servicecomb-java-chassis&Date) - # License Licensed under an [Apache 2.0 license](LICENSE). diff --git a/clients/config-center-client/pom.xml b/clients/config-center-client/pom.xml index 9729fd64b79..e7e2fa1fc2b 100644 --- a/clients/config-center-client/pom.xml +++ b/clients/config-center-client/pom.xml @@ -22,7 +22,7 @@ clients org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManager.java b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManager.java index 3b346153a0b..977c84ef63f 100644 --- a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManager.java +++ b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManager.java @@ -28,8 +28,9 @@ public class ConfigCenterAddressManager extends AbstractAddressManager { - public ConfigCenterAddressManager(String projectName, List addresses, EventBus eventBus) { - super(projectName, addresses); + public ConfigCenterAddressManager(String projectName, List addresses, EventBus eventBus, String region, + String availableZone) { + super(projectName, addresses, region, availableZone); eventBus.register(this); } diff --git a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterClient.java b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterClient.java index 4232c3db581..8ed31a5a61b 100644 --- a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterClient.java +++ b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterClient.java @@ -18,7 +18,9 @@ package org.apache.servicecomb.config.center.client; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; @@ -30,8 +32,11 @@ import org.apache.servicecomb.http.client.common.HttpResponse; import org.apache.servicecomb.http.client.common.HttpTransport; import org.apache.servicecomb.http.client.common.HttpUtils; +import org.apache.servicecomb.http.client.event.OperationEvents.UnAuthorizedOperationEvent; +import org.apache.servicecomb.http.client.utils.ServiceCombServiceAvailableUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.util.CollectionUtils; import com.fasterxml.jackson.core.type.TypeReference; import com.google.common.eventbus.EventBus; @@ -49,16 +54,23 @@ public class ConfigCenterClient implements ConfigCenterOperation { public static final String DARK_LAUNCH = "darklaunch@"; + private static final String ADDRESS_CHECK_PATH = "/v3/default/configuration/health?mode=readiness"; + private final HttpTransport httpTransport; private final ConfigCenterAddressManager addressManager; + private final Map> dimensionConfigNames = new HashMap<>(); + + private EventBus eventBus; + public ConfigCenterClient(ConfigCenterAddressManager addressManager, HttpTransport httpTransport) { this.addressManager = addressManager; this.httpTransport = httpTransport; } public void setEventBus(EventBus eventBus) { + this.eventBus = eventBus; addressManager.setEventBus(eventBus); } @@ -80,6 +92,7 @@ public QueryConfigurationsResponse queryConfigurations(QueryConfigurationsReques HttpRequest.GET); HttpResponse httpResponse = httpTransport.doRequest(httpRequest); + recordAndSendUnAuthorizedEvent(httpResponse, address); if (httpResponse.getStatusCode() == HttpStatus.SC_OK) { Map> allConfigMap = HttpUtils.deserialize( httpResponse.getContent(), @@ -92,31 +105,38 @@ public QueryConfigurationsResponse queryConfigurations(QueryConfigurationsReques if (allConfigMap.get(APPLICATION_CONFIG) != null) { configurations.putAll(allConfigMap.get(APPLICATION_CONFIG)); + logConfigurationNames(APPLICATION_CONFIG, allConfigMap.get(APPLICATION_CONFIG)); } if (allConfigMap.get(buildDimensionsInfo(request, false)) != null) { configurations.putAll(allConfigMap.get(buildDimensionsInfo(request, false))); + logConfigurationNames(buildDimensionsInfo(request, false), + allConfigMap.get(buildDimensionsInfo(request, false))); } if (allConfigMap.get(buildDarkLaunchDimensionsInfo(request)) != null) { configurations.putAll(allConfigMap.get(buildDarkLaunchDimensionsInfo(request))); + logConfigurationNames(buildDarkLaunchDimensionsInfo(request), + allConfigMap.get(buildDarkLaunchDimensionsInfo(request))); } if (allConfigMap.get(dimensionsInfo) != null) { configurations.putAll(allConfigMap.get(dimensionsInfo)); + logConfigurationNames(dimensionsInfo, allConfigMap.get(dimensionsInfo)); } queryConfigurationsResponse.setConfigurations(configurations); queryConfigurationsResponse.setChanged(true); - addressManager.recordSuccessState(address); return queryConfigurationsResponse; } else if (httpResponse.getStatusCode() == HttpStatus.SC_NOT_MODIFIED) { queryConfigurationsResponse.setChanged(false); - addressManager.recordSuccessState(address); + return queryConfigurationsResponse; + } else if (httpResponse.getStatusCode() == HttpStatus.SC_TOO_MANY_REQUESTS) { + LOGGER.warn("rate limited, keep the local dimension [{}] configs unchanged.", dimensionsInfo); + queryConfigurationsResponse.setChanged(false); return queryConfigurationsResponse; } else if (httpResponse.getStatusCode() == HttpStatus.SC_BAD_REQUEST) { throw new OperationException("Bad request for query configurations."); } else { - addressManager.recordFailState(address); throw new OperationException( "read response failed. status:" + httpResponse.getStatusCode() @@ -132,26 +152,51 @@ public QueryConfigurationsResponse queryConfigurations(QueryConfigurationsReques } } - @Override - public void checkAddressAvailable(QueryConfigurationsRequest request, String address) { - String dimensionsInfo = buildDimensionsInfo(request, true); - try { - String uri = address + "/configuration/items?dimensionsInfo=" - + HttpUtils.encodeURLParam(dimensionsInfo) + "&revision=" + request.getRevision(); - - Map headers = new HashMap<>(); - headers.put("x-environment", request.getEnvironment()); - HttpRequest httpRequest = new HttpRequest(uri, headers, null, - HttpRequest.GET); + private void recordAndSendUnAuthorizedEvent(HttpResponse response, String address) { + if (this.eventBus != null && response.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { + LOGGER.warn("query configuration unauthorized from server [{}], message [{}]", address, response.getMessage()); + addressManager.recordFailState(address); + this.eventBus.post(new UnAuthorizedOperationEvent(address)); + } else { + addressManager.recordSuccessState(address); + } + } - HttpResponse httpResponse = httpTransport.doRequest(httpRequest); - if (httpResponse.getStatusCode() == HttpStatus.SC_NOT_MODIFIED - || httpResponse.getStatusCode() == HttpStatus.SC_OK) { - addressManager.recoverIsolatedAddress(address); + /** + * Only the name of the new configuration item is printed. + * No log is printed when the configuration content is updated. + * + * @param dimension dimension + * @param configs configs + */ + private void logConfigurationNames(String dimension, Map configs) { + if (CollectionUtils.isEmpty(configs)) { + return; + } + List configNames = dimensionConfigNames.get(dimension); + if (configNames == null) { + configNames = new ArrayList<>(); + } + StringBuilder names = new StringBuilder(); + for (String key : configs.keySet()) { + if (configNames.contains(key)) { + continue; } - } catch (Exception e) { - LOGGER.error("check config center isolation address {} available error!", address); + names.append(key).append(","); + configNames.add(key); + } + if (names.isEmpty()) { + return; } + dimensionConfigNames.put(dimension, configNames); + String fileNames = names.substring(0, names.length() - 1); + LOGGER.info("pulling dimension [{}] configurations success, get config names: [{}].", + dimension, fileNames); + } + + @Override + public void checkAddressAvailable(String address) { + ServiceCombServiceAvailableUtils.checkAddressAvailable(addressManager, address, httpTransport, ADDRESS_CHECK_PATH); } private String buildDimensionsInfo(QueryConfigurationsRequest request, boolean withVersion) { diff --git a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterManager.java b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterManager.java index 66ee21621ed..7bfc43b4e05 100644 --- a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterManager.java +++ b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterManager.java @@ -91,7 +91,8 @@ public void execute() { startTask( new BackOffSleepTask(configCenterConfiguration.getRefreshIntervalInMillis(), new PollConfigurationTask(0))); } catch (Exception e) { - LOGGER.error("get configurations from ConfigCenter failed, and will try again.", e); + LOGGER.warn("get configurations from ConfigCenter failed, and will try again, cause message: {}. current " + + "fail does not affect the obtained historical configuration.", e.getCause().getMessage()); startTask(new BackOffSleepTask(failCount + 1, new PollConfigurationTask(failCount + 1))); } } @@ -105,7 +106,7 @@ public void run() { return; } for (String address : isolationAddresses) { - configCenterClient.checkAddressAvailable(queryConfigurationsRequest, address); + configCenterClient.checkAddressAvailable(address); } } } diff --git a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterOperation.java b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterOperation.java index 43b30c74831..919e9f30cd7 100644 --- a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterOperation.java +++ b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterOperation.java @@ -34,8 +34,7 @@ public interface ConfigCenterOperation { /** * Check config center isolation address available * - * @param request queryConfigurationsRequest * @param address isolation address */ - void checkAddressAvailable(QueryConfigurationsRequest request, String address); + void checkAddressAvailable(String address); } diff --git a/clients/config-common/pom.xml b/clients/config-common/pom.xml index 134c880d1e2..ff10b993583 100644 --- a/clients/config-common/pom.xml +++ b/clients/config-common/pom.xml @@ -22,7 +22,7 @@ clients org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/clients/config-kie-client/pom.xml b/clients/config-kie-client/pom.xml index 5aefd8084c5..30dac44ba53 100644 --- a/clients/config-kie-client/pom.xml +++ b/clients/config-kie-client/pom.xml @@ -22,7 +22,7 @@ clients org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java index b44ed0b1a25..b98a7d3b2a1 100644 --- a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java +++ b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java @@ -19,13 +19,14 @@ import com.google.common.eventbus.EventBus; -import java.io.IOException; import java.io.StringReader; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Properties; import java.util.stream.Collectors; @@ -45,15 +46,20 @@ import org.apache.servicecomb.http.client.common.HttpResponse; import org.apache.servicecomb.http.client.common.HttpTransport; import org.apache.servicecomb.http.client.common.HttpUtils; +import org.apache.servicecomb.http.client.event.OperationEvents.UnAuthorizedOperationEvent; +import org.apache.servicecomb.http.client.utils.ServiceCombServiceAvailableUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; import org.springframework.core.io.ByteArrayResource; +import org.springframework.util.CollectionUtils; public class KieClient implements KieConfigOperation { private static final Logger LOGGER = LoggerFactory.getLogger(KieClient.class); + private static final String ADDRESS_CHECK_PATH = "/v1/health"; + protected HttpTransport httpTransport; protected String revision = "0"; @@ -64,6 +70,10 @@ public class KieClient implements KieConfigOperation { public static final String DEFAULT_KIE_API_VERSION = "v1"; + private final Map> dimensionConfigNames = new HashMap<>(); + + private EventBus eventBus; + public KieClient(KieAddressManager addressManager, HttpTransport httpTransport, KieConfiguration kieConfiguration) { this.httpTransport = httpTransport; this.addressManager = addressManager; @@ -71,6 +81,7 @@ public KieClient(KieAddressManager addressManager, HttpTransport httpTransport, } public void setEventBus(EventBus eventBus) { + this.eventBus = eventBus; addressManager.setEventBus(eventBus); } @@ -84,15 +95,16 @@ public ConfigurationsResponse queryConfigurations(ConfigurationsRequest request, HttpRequest httpRequest = new HttpRequest(url, null, null, HttpRequest.GET); HttpResponse httpResponse = httpTransport.doRequest(httpRequest); + recordAndSendUnAuthorizedEvent(httpResponse, address); ConfigurationsResponse configurationsResponse = new ConfigurationsResponse(); if (httpResponse.getStatusCode() == HttpStatus.SC_OK) { revision = httpResponse.getHeader("X-Kie-Revision"); KVResponse allConfigList = HttpUtils.deserialize(httpResponse.getContent(), KVResponse.class); + logConfigurationNames(request.getLabelsQuery(), allConfigList.getData()); Map configurations = getConfigByLabel(allConfigList); configurationsResponse.setConfigurations(configurations); configurationsResponse.setChanged(true); configurationsResponse.setRevision(revision); - addressManager.recordSuccessState(address); return configurationsResponse; } if (httpResponse.getStatusCode() == HttpStatus.SC_BAD_REQUEST) { @@ -100,10 +112,13 @@ public ConfigurationsResponse queryConfigurations(ConfigurationsRequest request, } if (httpResponse.getStatusCode() == HttpStatus.SC_NOT_MODIFIED) { configurationsResponse.setChanged(false); - addressManager.recordSuccessState(address); return configurationsResponse; } - addressManager.recordFailState(address); + if (httpResponse.getStatusCode() == HttpStatus.SC_TOO_MANY_REQUESTS) { + LOGGER.warn("rate limited, keep the local dimension [{}] configs unchanged.", request.getLabelsQuery()); + configurationsResponse.setChanged(false); + return configurationsResponse; + } throw new OperationException( "read response failed. status:" + httpResponse.getStatusCode() + "; message:" + httpResponse.getMessage() + "; content:" + httpResponse.getContent()); @@ -114,19 +129,51 @@ public ConfigurationsResponse queryConfigurations(ConfigurationsRequest request, } } - @Override - public void checkAddressAvailable(ConfigurationsRequest request, String address) { - String url = buildUrl(request, address); - HttpRequest httpRequest = new HttpRequest(url, null, null, HttpRequest.GET); - try { - HttpResponse httpResponse = httpTransport.doRequest(httpRequest); - if (httpResponse.getStatusCode() == HttpStatus.SC_NOT_MODIFIED - || httpResponse.getStatusCode() == HttpStatus.SC_OK) { - addressManager.recoverIsolatedAddress(address); + private void recordAndSendUnAuthorizedEvent(HttpResponse response, String address) { + if (this.eventBus != null && response.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { + LOGGER.warn("query configuration unauthorized from server [{}], message [{}]", address, response.getMessage()); + addressManager.recordFailState(address); + this.eventBus.post(new UnAuthorizedOperationEvent(address)); + } else { + addressManager.recordSuccessState(address); + } + } + + /** + * Only the name of the new configuration item is printed. + * No log is printed when the configuration content is updated. + * + * @param dimension dimension + * @param data configs-data + */ + private void logConfigurationNames(String dimension, List data) { + if (CollectionUtils.isEmpty(data)) { + return; + } + List configNames = dimensionConfigNames.get(dimension); + if (configNames == null) { + configNames = new ArrayList<>(); + } + StringBuilder names = new StringBuilder(); + for (KVDoc doc : data) { + if (configNames.contains(doc.getKey())) { + continue; } - } catch (IOException e) { - LOGGER.error("check kie config isolation address {} available error!", address); + names.append(doc.getKey()).append(","); + configNames.add(doc.getKey()); + } + if (names.isEmpty()) { + return; } + dimensionConfigNames.put(dimension, configNames); + String fileNames = names.substring(0, names.length() - 1); + LOGGER.info("pulling dimension [{}] configurations success, get config names: [{}].", + dimension, fileNames); + } + + @Override + public void checkAddressAvailable(String address) { + ServiceCombServiceAvailableUtils.checkAddressAvailable(addressManager, address, httpTransport, ADDRESS_CHECK_PATH); } private String buildUrl(ConfigurationsRequest request, String currentAddress) { diff --git a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigManager.java b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigManager.java index d6ed9ca0e7f..ed251613530 100644 --- a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigManager.java +++ b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigManager.java @@ -124,7 +124,7 @@ protected void initTaskPool(String taskName) { public void startConfigKieManager() { this.configurationsRequests.forEach((t) -> this.startTask(new PollConfigurationTask(0, t))); - schedulerCheckAddressAvailable("kie-addr-check", new CheckKieAddressTask(configurationsRequests.get(0)), + schedulerCheckAddressAvailable("kie-addr-check", new CheckKieAddressTask(), kieConfiguration.getRefreshIntervalInMillis()); } @@ -156,7 +156,8 @@ public void execute() { new PollConfigurationTask(0, this.configurationsRequest))); } } catch (Exception e) { - LOGGER.error("get configurations from KieConfigCenter failed, and will try again.", e); + LOGGER.warn("get configurations from KieConfigCenter failed, and will try again, cause message: {}. current " + + "fail does not affect the obtained historical configuration.", e.getCause().getMessage()); startTask( new BackOffSleepTask(failCount + 1, new PollConfigurationTask(failCount + 1, this.configurationsRequest))); } @@ -164,12 +165,6 @@ public void execute() { } class CheckKieAddressTask implements Runnable { - ConfigurationsRequest configurationsRequest; - - public CheckKieAddressTask(ConfigurationsRequest configurationsRequest) { - this.configurationsRequest = configurationsRequest; - } - @Override public void run() { List isolationAddresses = kieAddressManager.getIsolationAddresses(); @@ -177,7 +172,7 @@ public void run() { return; } for (String address : isolationAddresses) { - configKieClient.checkAddressAvailable(this.configurationsRequest, address); + configKieClient.checkAddressAvailable(address); } } } diff --git a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigOperation.java b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigOperation.java index 44f66137fef..135ad0c220a 100644 --- a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigOperation.java +++ b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieConfigOperation.java @@ -35,8 +35,7 @@ public interface KieConfigOperation { /** * Check kie isolation address available * - * @param configurationsRequest configurationsRequest * @param address isolation address */ - void checkAddressAvailable(ConfigurationsRequest configurationsRequest, String address); + void checkAddressAvailable(String address); } diff --git a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieAddressManager.java b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieAddressManager.java index 0742c11fb10..d8c069ee9b1 100644 --- a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieAddressManager.java +++ b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieAddressManager.java @@ -27,8 +27,8 @@ public class KieAddressManager extends AbstractAddressManager { - public KieAddressManager(List addresses, EventBus eventBus) { - super(addresses); + public KieAddressManager(List addresses, EventBus eventBus, String region, String availableZone) { + super(addresses, region, availableZone); eventBus.register(this); } diff --git a/clients/config-kie-client/src/test/java/org/apache/servicecomb/config/kie/client/model/KieAddressManagerTest.java b/clients/config-kie-client/src/test/java/org/apache/servicecomb/config/kie/client/model/KieAddressManagerTest.java index 6533fc60e57..c8bf1f57a29 100644 --- a/clients/config-kie-client/src/test/java/org/apache/servicecomb/config/kie/client/model/KieAddressManagerTest.java +++ b/clients/config-kie-client/src/test/java/org/apache/servicecomb/config/kie/client/model/KieAddressManagerTest.java @@ -40,7 +40,7 @@ class KieAddressManagerTest { public void kieAddressManagerTest() throws NoSuchFieldException, IllegalAccessException { addresses.add("http://127.0.0.1:30103"); addresses.add("https://127.0.0.2:30103"); - addressManager1 = new KieAddressManager(addresses, new EventBus()); + addressManager1 = new KieAddressManager(addresses, new EventBus(), "", ""); Field addressManagerField = addressManager1.getClass().getSuperclass().getDeclaredField("index"); addressManagerField.setAccessible(true); addressManagerField.set(addressManager1, 0); @@ -64,7 +64,7 @@ public void onRefreshEndpointEvent() { Map> zoneAndRegion = new HashMap<>(); zoneAndRegion.put("sameZone", addressAZ); zoneAndRegion.put("sameRegion", addressRG); - addressManager1 = new KieAddressManager(addresses, new EventBus()); + addressManager1 = new KieAddressManager(addresses, new EventBus(), "", ""); RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, "KIE"); addressManager1.refreshEndpoint(event, "KIE"); diff --git a/clients/dashboard-client/pom.xml b/clients/dashboard-client/pom.xml index 8eb33b47f00..fb40407b82a 100644 --- a/clients/dashboard-client/pom.xml +++ b/clients/dashboard-client/pom.xml @@ -22,7 +22,7 @@ clients org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/clients/dashboard-client/src/main/java/org/apache/servicecomb/dashboard/client/DashboardAddressManager.java b/clients/dashboard-client/src/main/java/org/apache/servicecomb/dashboard/client/DashboardAddressManager.java index 9dd8c6a3448..6897e02acd4 100644 --- a/clients/dashboard-client/src/main/java/org/apache/servicecomb/dashboard/client/DashboardAddressManager.java +++ b/clients/dashboard-client/src/main/java/org/apache/servicecomb/dashboard/client/DashboardAddressManager.java @@ -29,8 +29,8 @@ public class DashboardAddressManager extends AbstractAddressManager { - public DashboardAddressManager(List addresses, EventBus eventBus) { - super(addresses); + public DashboardAddressManager(List addresses, EventBus eventBus, String region, String availableZone) { + super(addresses, region, availableZone); eventBus.register(this); } diff --git a/clients/dashboard-client/src/test/java/org/apache/servicecomb/dashboard/client/AddressManagerTest.java b/clients/dashboard-client/src/test/java/org/apache/servicecomb/dashboard/client/AddressManagerTest.java index 71e5deedaf7..fdb7a23922b 100644 --- a/clients/dashboard-client/src/test/java/org/apache/servicecomb/dashboard/client/AddressManagerTest.java +++ b/clients/dashboard-client/src/test/java/org/apache/servicecomb/dashboard/client/AddressManagerTest.java @@ -39,7 +39,7 @@ class AddressManagerTest { public void kieAddressManagerTest() throws IllegalAccessException, NoSuchFieldException { addresses.add("http://127.0.0.1:30103"); addresses.add("https://127.0.0.2:30103"); - addressManager1 = new DashboardAddressManager(addresses, new EventBus()); + addressManager1 = new DashboardAddressManager(addresses, new EventBus(), "", ""); Field addressManagerField = addressManager1.getClass().getSuperclass().getDeclaredField("index"); addressManagerField.setAccessible(true); addressManagerField.set(addressManager1, 0); @@ -63,7 +63,7 @@ public void onRefreshEndpointEvent() { Map> zoneAndRegion = new HashMap<>(); zoneAndRegion.put("sameZone", addressAZ); zoneAndRegion.put("sameRegion", addressRG); - addressManager1 = new DashboardAddressManager(addresses, new EventBus()); + addressManager1 = new DashboardAddressManager(addresses, new EventBus(), "", ""); RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, "CseMonitoring"); addressManager1.refreshEndpoint(event, "CseMonitoring"); diff --git a/clients/http-client-common/pom.xml b/clients/http-client-common/pom.xml index d4f40de5111..51d982e470c 100644 --- a/clients/http-client-common/pom.xml +++ b/clients/http-client-common/pom.xml @@ -22,7 +22,7 @@ clients org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/AbstractAddressManager.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/AbstractAddressManager.java index 5c4bc71dc8e..3c5d6214be8 100644 --- a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/AbstractAddressManager.java +++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/AbstractAddressManager.java @@ -17,6 +17,7 @@ package org.apache.servicecomb.http.client.common; +import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -29,6 +30,7 @@ import org.apache.servicecomb.http.client.event.RefreshEndpointEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.util.CollectionUtils; import com.google.common.annotations.VisibleForTesting; import com.google.common.eventbus.EventBus; @@ -42,6 +44,10 @@ public class AbstractAddressManager { private static final String V3_PREFIX = "/v3/"; + private static final String ZONE = "availableZone"; + + private static final String REGION = "region"; + private static final int ISOLATION_THRESHOLD = 3; private volatile List addresses = new ArrayList<>(); @@ -66,7 +72,7 @@ public class AbstractAddressManager { private final List isolationRegionAddress = new ArrayList<>(); - private boolean addressAutoRefreshed = false; + private volatile boolean addressAutoRefreshed = false; private final Object lock = new Object(); @@ -74,17 +80,63 @@ public class AbstractAddressManager { private EventBus eventBus; - public AbstractAddressManager(List addresses) { + public AbstractAddressManager(List addresses, String ownRegion, String ownAvailableZone) { this.projectName = DEFAULT_PROJECT; - this.addresses.addAll(addresses); - this.defaultAddress.addAll(addresses); + parseAndInitAddresses(addresses, ownRegion, ownAvailableZone, false); this.index = !addresses.isEmpty() ? getRandomIndex() : 0; } - public AbstractAddressManager(String projectName, List addresses) { + /** + * address support config with region/availableZone info, to enable engine affinity calls during startup + * address may be like: + * https://192.168.20.13:30110?region=region1&availableZone=az + * https://192.168.20.13:30100?region=region1&availableZone=az + * When address have no datacenter information, roundRobin using address + * + * @param addresses engine addresses + * @param ownRegion microservice region + * @param ownAvailableZone microservice zone + * @param isFormat is need format + */ + private void parseAndInitAddresses(List addresses, String ownRegion, String ownAvailableZone, + boolean isFormat) { + if (CollectionUtils.isEmpty(addresses)) { + return; + } + List tempList = new ArrayList<>(); + addressAutoRefreshed = addresses.stream().anyMatch(addr -> addr.contains(ZONE) || addr.contains(REGION)); + for (String address : addresses) { + // Compatible IpPortManager init address is 127.0.0.1:30100 + if (!address.startsWith("http")) { + tempList.add(address); + continue; + } + URLEndPoint endpoint = new URLEndPoint(address); + tempList.add(endpoint.toString()); + buildAffinityAddress(endpoint, ownRegion, ownAvailableZone); + } + this.addresses.addAll(isFormat ? this.transformAddress(tempList) : tempList); + this.defaultAddress.addAll(isFormat ? this.transformAddress(tempList) : tempList); + } + + private void buildAffinityAddress(URLEndPoint endpoint, String ownRegion, String ownAvailableZone) { + if (addressAutoRefreshed) { + if (regionAndAZMatch(ownRegion, ownAvailableZone, endpoint.getFirst(REGION), endpoint.getFirst(ZONE))) { + availableZone.add(endpoint.toString()); + } else { + availableRegion.add(endpoint.toString()); + } + } + } + + private boolean regionAndAZMatch(String ownRegion, String ownAvailableZone, String engineRegion, + String engineAvailableZone) { + return ownRegion.equalsIgnoreCase(engineRegion) && ownAvailableZone.equals(engineAvailableZone); + } + + public AbstractAddressManager(String projectName, List addresses, String ownRegion, String ownAvailableZone) { this.projectName = StringUtils.isEmpty(projectName) ? DEFAULT_PROJECT : projectName; - this.addresses = this.transformAddress(addresses); - this.defaultAddress.addAll(addresses); + parseAndInitAddresses(addresses, ownRegion, ownAvailableZone, true); this.index = !addresses.isEmpty() ? getRandomIndex() : 0; } @@ -194,8 +246,8 @@ private List getZoneOrRegionAddress() { return results; } - public void recoverIsolatedAddress(String address) { - recordSuccessState(address); + public void recordSuccessState(String address) { + resetFailureStatus(address); if (addressAutoRefreshed) { if (isolationZoneAddress.remove(address)) { LOGGER.warn("restore same region address [{}]", address); @@ -217,7 +269,7 @@ public void recoverIsolatedAddress(String address) { } } - public void recordSuccessState(String address) { + public void resetFailureStatus(String address) { addressFailureStatus.put(address, 0); } @@ -271,4 +323,26 @@ public List getIsolationAddresses() { isolationAddresses.addAll(isolationRegionAddress); return isolationAddresses; } + + public String compareAndGetAddress(String host) { + for (String address : defaultAddress) { + if (isAddressHostSame(address, host)) { + return address; + } + } + return ""; + } + + private boolean isAddressHostSame(String address, String host) { + if (StringUtils.isEmpty(host)) { + return false; + } + try { + URI uri = new URI(address); + return host.equals(uri.getHost()); + } catch (Exception e) { + LOGGER.warn("Exception occurred while constructing URI using the address [{}]", address); + } + return false; + } } diff --git a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java index da87892929c..507d8d1c556 100644 --- a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java +++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java @@ -18,17 +18,21 @@ package org.apache.servicecomb.http.client.common; import java.io.IOException; +import java.net.URI; import java.util.Map; import org.apache.http.client.HttpClient; import org.apache.http.util.EntityUtils; import org.apache.servicecomb.foundation.auth.SignRequest; import org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Created by on 2019/10/16. */ public class HttpTransportImpl implements HttpTransport { + private static final Logger LOGGER = LoggerFactory.getLogger(HttpTransportImpl.class); private static final String HEADER_CONTENT_TYPE = "Content-Type"; @@ -87,7 +91,7 @@ public HttpResponse doRequest(HttpRequest httpRequest) throws IOException { globalHeaders.forEach(httpRequest::addHeader); } - httpRequest.getHeaders().putAll(requestAuthHeaderProvider.loadAuthHeader(createSignRequest())); + httpRequest.getHeaders().putAll(requestAuthHeaderProvider.loadAuthHeader(createSignRequest(httpRequest.getUrl()))); //get Http response org.apache.http.HttpResponse response = httpClient.execute(httpRequest.getRealRequest()); @@ -98,9 +102,16 @@ public HttpResponse doRequest(HttpRequest httpRequest) throws IOException { response.getAllHeaders()); } - private static SignRequest createSignRequest() { - // Now the implementations do not process SignRequest, so return null. Maybe future will use it. - return null; + private static SignRequest createSignRequest(String url) { + try { + URI uri = URI.create(url); + SignRequest signRequest = new SignRequest(); + signRequest.setEndpoint(uri); + return signRequest; + } catch (Exception e) { + LOGGER.error("create signRequest failed!", e); + return null; + } } @Override diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/OperationEvents.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/event/OperationEvents.java similarity index 79% rename from clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/OperationEvents.java rename to clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/event/OperationEvents.java index 62274519ea4..69896f750ec 100644 --- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/OperationEvents.java +++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/event/OperationEvents.java @@ -15,10 +15,18 @@ * limitations under the License. */ -package org.apache.servicecomb.service.center.client; +package org.apache.servicecomb.http.client.event; public abstract class OperationEvents { public static class UnAuthorizedOperationEvent extends OperationEvents { + private final String address; + public UnAuthorizedOperationEvent(String address) { + this.address = address; + } + + public String getAddress() { + return address; + } } } diff --git a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/task/AbstractTask.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/task/AbstractTask.java index d25dee151de..cc10ae8e142 100644 --- a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/task/AbstractTask.java +++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/task/AbstractTask.java @@ -31,7 +31,7 @@ public class AbstractTask { public class BackOffSleepTask implements Task { private static final long BASE = 3000; - private static final long MAX = 10 * 60 * 10000; + private static final long MAX = 10 * 60 * 1000; long waitTime; diff --git a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/utils/ServiceCombServiceAvailableUtils.java b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/utils/ServiceCombServiceAvailableUtils.java new file mode 100644 index 00000000000..9139e65f96a --- /dev/null +++ b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/utils/ServiceCombServiceAvailableUtils.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.http.client.utils; + +import org.apache.http.HttpStatus; +import org.apache.servicecomb.http.client.common.AbstractAddressManager; +import org.apache.servicecomb.http.client.common.HttpRequest; +import org.apache.servicecomb.http.client.common.HttpResponse; +import org.apache.servicecomb.http.client.common.HttpTransport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.URI; +import java.net.URISyntaxException; + +public class ServiceCombServiceAvailableUtils { + private static final Logger LOGGER = LoggerFactory.getLogger(ServiceCombServiceAvailableUtils.class); + + public static void checkAddressAvailable(AbstractAddressManager addressManager, String address, + HttpTransport httpTransport, String path) { + String formatUrl = addressManager.formatUrl(path, true, address); + HttpRequest httpRequest = new HttpRequest(formatUrl, null, null, HttpRequest.GET); + try { + HttpResponse response = httpTransport.doRequest(httpRequest); + if (response.getStatusCode() == HttpStatus.SC_OK) { + addressManager.recordSuccessState(address); + return; + } + + // old server does not provide the check api, using TCP checks whether the server is ready. + if (response.getStatusCode() == HttpStatus.SC_NOT_FOUND && telnetCheckAddress(address)) { + LOGGER.warn("[{}] path does not provide, tcp check address ready!", path); + addressManager.recordSuccessState(address); + } + } catch (IOException e) { + LOGGER.error("check isolation address [{}] available error!", address); + } + } + + private static boolean telnetCheckAddress(String address) { + URI ipPort = parseIpPortFromURI(address); + if (ipPort == null) { + return false; + } + try (Socket s = new Socket()) { + s.connect(new InetSocketAddress(ipPort.getHost(), ipPort.getPort()), 3000); + return true; + } catch (IOException e) { + LOGGER.warn("ping endpoint {} failed, It will be quarantined again.", address); + } + return false; + } + + private static URI parseIpPortFromURI(String address) { + try { + return new URI(address); + } catch (URISyntaxException e) { + LOGGER.error("build uri error with address [{}].", address); + return null; + } + } +} diff --git a/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/AbstractAddressManagerTest.java b/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/AbstractAddressManagerTest.java index 83406ec747e..b14d6827cb8 100644 --- a/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/AbstractAddressManagerTest.java +++ b/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/AbstractAddressManagerTest.java @@ -46,9 +46,9 @@ public class AbstractAddressManagerTest { public void setUp() throws NoSuchFieldException, IllegalAccessException { addresses.add("http://127.0.0.1:30103"); addresses.add("https://127.0.0.2:30103"); - addressManager1 = new AbstractAddressManager(addresses); - addressManager2 = new AbstractAddressManager("project", addresses); - addressManager3 = new AbstractAddressManager(null, addresses); + addressManager1 = new AbstractAddressManager(addresses, "", ""); + addressManager2 = new AbstractAddressManager("project", addresses, "", ""); + addressManager3 = new AbstractAddressManager(null, addresses, "", ""); Field addressManagerField = addressManager1.getClass().getDeclaredField("index"); addressManagerField.setAccessible(true); addressManagerField.set(addressManager1, 0); @@ -88,7 +88,7 @@ public void recordStateTest() throws ExecutionException { zoneAndRegion.put("sameZone", addressAZ); zoneAndRegion.put("sameRegion", addressRG); RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, "TEST"); - AbstractAddressManager addressManager = new AbstractAddressManager(addresses) {}; + AbstractAddressManager addressManager = new AbstractAddressManager(addresses, "", "") {}; addressManager.refreshEndpoint(event, "TEST"); @@ -101,7 +101,7 @@ public void recordStateTest() throws ExecutionException { Assertions.assertEquals("http://127.0.0.3:30100", addressManager.address()); // test fail 2 times ,it will not be isolated - addressManager.recordSuccessState(address); + addressManager.resetFailureStatus(address); Assertions.assertEquals("http://127.0.0.3:30100", addressManager.address()); // test recodeStatus times @@ -115,7 +115,7 @@ public void recordStateTest() throws ExecutionException { Assertions.assertEquals("http://127.0.0.4:30100", addressManager.address()); // test restore isolation - addressManager.recoverIsolatedAddress("http://127.0.0.3:30100"); + addressManager.recordSuccessState("http://127.0.0.3:30100"); Assertions.assertEquals("http://127.0.0.3:30100", addressManager.address()); Assertions.assertEquals("http://127.0.0.3:30100", addressManager.address()); } @@ -124,7 +124,7 @@ public void recordStateTest() throws ExecutionException { @Test public void testMultipleThread() throws Exception { - AbstractAddressManager addressManager = new AbstractAddressManager(addresses); + AbstractAddressManager addressManager = new AbstractAddressManager(addresses, "", ""); String address = "http://127.0.0.3:30100"; CountDownLatch latch = new CountDownLatch(2); @@ -302,4 +302,27 @@ public void normalizeIPV6Test() { uri = addressManager1.normalizeUri("rest://[2008::7:957f:b2d6:1af4:a1f8]:30100"); Assertions.assertEquals("http://[2008::7:957f:b2d6:1af4:a1f8]:30100", uri); } + + @Test + public void compareAndGetAddressTest() { + List testAddr = new ArrayList<>(); + testAddr.add("https://192.168.20.160:30100"); + testAddr.add("https://127.0.0.1:30100"); + testAddr.add("https://127.0.0.3:30100"); + AbstractAddressManager manager = new AbstractAddressManager(testAddr, "", ""); + Assertions.assertTrue(manager.compareAndGetAddress("192.168.20.16").isEmpty()); + Assertions.assertEquals("https://192.168.20.160:30100", manager.compareAndGetAddress("192.168.20.160")); + } + + @Test + public void AddressAffinityTest() { + List testAddr = new ArrayList<>(); + testAddr.add("https://192.168.20.160:30100?region=region1&availableZone=zone1"); + testAddr.add("https://127.0.0.1:30100"); + AbstractAddressManager manager = new AbstractAddressManager(testAddr, "region1", "zone1"); + Assertions.assertEquals("https://192.168.20.160:30100", manager.address()); + + AbstractAddressManager manager2 = new AbstractAddressManager("default", testAddr, "region1", "zone1"); + Assertions.assertEquals("https://192.168.20.160:30100", manager2.address()); + } } diff --git a/clients/pom.xml b/clients/pom.xml index 0b2abcffd74..49f481934cc 100644 --- a/clients/pom.xml +++ b/clients/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default 4.0.0 diff --git a/clients/service-center-client/pom.xml b/clients/service-center-client/pom.xml index 47a4ff5a8ff..ccc3900e9db 100755 --- a/clients/service-center-client/pom.xml +++ b/clients/service-center-client/pom.xml @@ -22,7 +22,7 @@ clients org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManager.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManager.java index a5fd128ab1e..b19db919e81 100644 --- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManager.java +++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManager.java @@ -26,8 +26,9 @@ import com.google.common.eventbus.Subscribe; public class ServiceCenterAddressManager extends AbstractAddressManager { - public ServiceCenterAddressManager(String projectName, List addresses, EventBus eventBus) { - super(projectName, addresses); + public ServiceCenterAddressManager(String projectName, List addresses, EventBus eventBus, String region, + String availableZone) { + super(projectName, addresses, region, availableZone); eventBus.register(this); } diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java index 45c4c27dc01..97aeaa9931a 100755 --- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java +++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java @@ -25,6 +25,7 @@ import java.util.Map; import org.apache.http.HttpStatus; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.utils.URIBuilder; import org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider; import org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties; @@ -32,13 +33,13 @@ import org.apache.servicecomb.http.client.common.HttpTransport; import org.apache.servicecomb.http.client.common.HttpTransportFactory; import org.apache.servicecomb.http.client.common.HttpUtils; -import org.apache.servicecomb.service.center.client.OperationEvents.UnAuthorizedOperationEvent; import org.apache.servicecomb.service.center.client.exception.OperationException; import org.apache.servicecomb.service.center.client.model.CreateMicroserviceInstanceRequest; import org.apache.servicecomb.service.center.client.model.CreateMicroserviceRequest; import org.apache.servicecomb.service.center.client.model.CreateSchemaRequest; import org.apache.servicecomb.service.center.client.model.ErrorMessage; import org.apache.servicecomb.service.center.client.model.FindMicroserviceInstancesResponse; +import org.apache.servicecomb.service.center.client.model.Framework; import org.apache.servicecomb.service.center.client.model.GetSchemaListResponse; import org.apache.servicecomb.service.center.client.model.GetSchemaResponse; import org.apache.servicecomb.service.center.client.model.HeartbeatsRequest; @@ -58,6 +59,7 @@ import org.apache.servicecomb.service.center.client.model.UpdatePropertiesRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.core.env.Environment; import com.google.common.eventbus.EventBus; @@ -65,19 +67,24 @@ public class ServiceCenterClient implements ServiceCenterOperation { private static final Logger LOGGER = LoggerFactory.getLogger(ServiceCenterClient.class); - private final ServiceCenterRawClient httpClient; + private static final String CLIENT_CONNECT_TIMEOUT = "servicecomb.registry.sc.client.timeout.connect"; + + private static final String CLIENT_REQUEST_TIMEOUT = "servicecomb.registry.sc.client.timeout.request"; - private EventBus eventBus; + private static final String CLIENT_SOCKET_TIMEOUT = "servicecomb.registry.sc.client.timeout.socket"; + + private final ServiceCenterRawClient httpClient; - private ServiceCenterAddressManager addressManager; + private final ServiceCenterAddressManager addressManager; - public ServiceCenterClient(ServiceCenterRawClient httpClient) { + public ServiceCenterClient(ServiceCenterRawClient httpClient, ServiceCenterAddressManager addressManager) { this.httpClient = httpClient; + this.addressManager = addressManager; } public ServiceCenterClient setEventBus(EventBus eventBus) { - this.eventBus = eventBus; addressManager.setEventBus(eventBus); + this.httpClient.setEventBus(eventBus); return this; } @@ -85,8 +92,10 @@ public ServiceCenterClient(ServiceCenterAddressManager addressManager, SSLProperties sslProperties, RequestAuthHeaderProvider requestAuthHeaderProvider, String tenantName, - Map extraGlobalHeaders) { - HttpTransport httpTransport = HttpTransportFactory.createHttpTransport(sslProperties, requestAuthHeaderProvider); + Map extraGlobalHeaders, + Environment environment) { + HttpTransport httpTransport = HttpTransportFactory.createHttpTransport(sslProperties, requestAuthHeaderProvider, + buildRequestConfig(environment)); httpTransport.addHeaders(extraGlobalHeaders); this.httpClient = new ServiceCenterRawClient.Builder() @@ -96,6 +105,17 @@ public ServiceCenterClient(ServiceCenterAddressManager addressManager, this.addressManager = addressManager; } + private RequestConfig buildRequestConfig(Environment environment) { + RequestConfig.Builder builder = HttpTransportFactory.defaultRequestConfig(); + if (environment == null) { + return builder.build(); + } + builder.setConnectTimeout(environment.getProperty(CLIENT_CONNECT_TIMEOUT, int.class, 5000)); + builder.setConnectionRequestTimeout(environment.getProperty(CLIENT_REQUEST_TIMEOUT, int.class, 5000)); + builder.setSocketTimeout(environment.getProperty(CLIENT_SOCKET_TIMEOUT, int.class, 5000)); + return builder.build(); + } + @Override public MicroserviceInstancesResponse getServiceCenterInstances() { try { @@ -103,7 +123,6 @@ public MicroserviceInstancesResponse getServiceCenterInstances() { if (response.getStatusCode() == HttpStatus.SC_OK) { return HttpUtils.deserialize(response.getContent(), MicroserviceInstancesResponse.class); } - sendUnAuthorizedEvent(response); throw new OperationException( "get service-center instances fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -124,7 +143,6 @@ public RegisteredMicroserviceResponse registerMicroservice(Microservice microser if (response.getStatusCode() == HttpStatus.SC_OK) { return HttpUtils.deserialize(response.getContent(), RegisteredMicroserviceResponse.class); } - sendUnAuthorizedEvent(response); throw new OperationException( "register service fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -142,7 +160,6 @@ public MicroservicesResponse getMicroserviceList() { if (response.getStatusCode() == HttpStatus.SC_OK) { return HttpUtils.deserialize(response.getContent(), MicroservicesResponse.class); } - sendUnAuthorizedEvent(response); throw new OperationException( "get service List fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -167,7 +184,6 @@ public RegisteredMicroserviceResponse queryServiceId(Microservice microservice) if (response.getStatusCode() == HttpStatus.SC_OK) { return HttpUtils.deserialize(response.getContent(), RegisteredMicroserviceResponse.class); } - sendUnAuthorizedEvent(response); LOGGER.info("Query serviceId fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() + "; content = " + response.getContent()); @@ -190,7 +206,6 @@ public Microservice getMicroserviceByServiceId(String serviceId) { .deserialize(response.getContent(), MicroserviceResponse.class); return microserviceResponse.getService(); } - sendUnAuthorizedEvent(response); throw new OperationException( "get service message fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -212,7 +227,6 @@ public RegisteredMicroserviceInstanceResponse registerMicroserviceInstance(Micro if (response.getStatusCode() == HttpStatus.SC_OK) { return HttpUtils.deserialize(response.getContent(), RegisteredMicroserviceInstanceResponse.class); } - sendUnAuthorizedEvent(response); throw new OperationException( "register service instance fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -248,7 +262,11 @@ public FindMicroserviceInstancesResponse findMicroserviceInstance(String consume result.setModified(false); return result; } - sendUnAuthorizedEvent(response); + if (response.getStatusCode() == HttpStatus.SC_TOO_MANY_REQUESTS) { + LOGGER.warn("rate limited, keep the local service {}#{} instance cache unchanged.", appId, serviceName); + result.setModified(false); + return result; + } throw new OperationException( "get service instances list fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -267,7 +285,6 @@ public MicroserviceInstancesResponse getMicroserviceInstanceList(String serviceI if (response.getStatusCode() == HttpStatus.SC_OK) { return HttpUtils.deserialize(response.getContent(), MicroserviceInstancesResponse.class); } - sendUnAuthorizedEvent(response); throw new OperationException( "get service instances list fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -288,7 +305,6 @@ public MicroserviceInstance getMicroserviceInstance(String serviceId, String ins .deserialize(response.getContent(), MicroserviceInstanceResponse.class); return instanceResponse.getInstance(); } - sendUnAuthorizedEvent(response); throw new OperationException( "get service instance message fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -308,7 +324,6 @@ public void deleteMicroserviceInstance(String serviceId, String instanceId) { LOGGER.info("Delete service instance successfully."); return; } - sendUnAuthorizedEvent(response); throw new OperationException( "delete service instance fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -328,7 +343,6 @@ public boolean updateMicroserviceInstanceStatus(String serviceId, String instanc if (response.getStatusCode() == HttpStatus.SC_OK) { return true; } - sendUnAuthorizedEvent(response); throw new OperationException( "update service instance status fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -347,7 +361,6 @@ public void sendHeartBeats(HeartbeatsRequest heartbeatsRequest) { if (response.getStatusCode() == HttpStatus.SC_OK) { return; } - sendUnAuthorizedEvent(response); throw new OperationException( "heartbeats fails, statusCode = " + response.getStatusCode() + "; message = " + response.getMessage() + "; content = " + response.getContent()); @@ -367,7 +380,6 @@ public boolean sendHeartBeat(String serviceId, String instanceId) { if (response.getStatusCode() == HttpStatus.SC_OK) { return true; } - sendUnAuthorizedEvent(response); throw new OperationException( "heartbeats fails, statusCode = " + response.getStatusCode() + "; message = " + response.getMessage() + "; content = " + response.getContent()); @@ -392,7 +404,6 @@ public List getServiceSchemasList(String serviceId, boolean withCont .deserialize(response.getContent(), GetSchemaListResponse.class); return getSchemaResponse.getSchemas(); } - sendUnAuthorizedEvent(response); throw new OperationException( "get service schemas list fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -419,7 +430,6 @@ public String getServiceSchemaContext(String serviceId, String schemaId) { GetSchemaResponse getSchemaResponse = HttpUtils.deserialize(response.getContent(), GetSchemaResponse.class); return getSchemaResponse.getSchema(); } - sendUnAuthorizedEvent(response); throw new OperationException( "get service schema context fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -439,7 +449,6 @@ public boolean registerSchema(String serviceId, String schemaId, CreateSchemaReq if (response.getStatusCode() == HttpStatus.SC_OK) { return true; } - sendUnAuthorizedEvent(response); throw new OperationException( "update service schema fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -462,7 +471,6 @@ public boolean updateServiceSchemaContext(String serviceId, SchemaInfo schemaInf if (response.getStatusCode() == HttpStatus.SC_OK) { return true; } - sendUnAuthorizedEvent(response); throw new OperationException( "update service schema fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -482,7 +490,6 @@ public boolean batchUpdateServiceSchemaContext(String serviceId, ModifySchemasRe if (response.getStatusCode() == HttpStatus.SC_OK) { return true; } - sendUnAuthorizedEvent(response); throw new OperationException( "update service schema fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() @@ -493,18 +500,12 @@ public boolean batchUpdateServiceSchemaContext(String serviceId, ModifySchemasRe } } - private void sendUnAuthorizedEvent(HttpResponse response) { - if (this.eventBus != null && response.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { - this.eventBus.post(new UnAuthorizedOperationEvent()); - } - } - @Override - public RbacTokenResponse queryToken(RbacTokenRequest request) { + public RbacTokenResponse queryToken(RbacTokenRequest request, String host) { try { + String queryAddress = addressManager.compareAndGetAddress(host); HttpResponse response = httpClient - .postHttpRequestAbsoluteUrl("/v4/token", null, - HttpUtils.serialize(request)); + .postHttpRequestAbsoluteUrl("/v4/token", null, HttpUtils.serialize(request), queryAddress); if (response.getStatusCode() == HttpStatus.SC_OK) { RbacTokenResponse result = HttpUtils.deserialize(response.getContent(), RbacTokenResponse.class); result.setStatusCode(HttpStatus.SC_OK); @@ -534,23 +535,24 @@ public RbacTokenResponse queryToken(RbacTokenRequest request) { } @Override - public boolean updateMicroserviceProperties(String serviceId, Map serviceProperties) { + public boolean updateMicroserviceProperties(String serviceId, Map serviceProperties, + Framework framework) { try { UpdatePropertiesRequest request = new UpdatePropertiesRequest(); request.setProperties(serviceProperties); + request.setFramework(framework); HttpResponse response = httpClient.putHttpRequest( "/registry/microservices/" + serviceId + "/properties", null, HttpUtils.serialize(request)); if (response.getStatusCode() == HttpStatus.SC_OK) { return true; } - sendUnAuthorizedEvent(response); throw new OperationException( - "update service instance status fails, statusCode = " + response.getStatusCode() + "; message = " + response + "update service properties fails, statusCode = " + response.getStatusCode() + "; message = " + response .getMessage() + "; content = " + response.getContent()); } catch (IOException e) { throw new OperationException( - "update service instance status fails", e); + "update service properties fails", e); } } @@ -561,7 +563,7 @@ public void checkIsolationAddressAvailable() { return; } for (String address : isolationAddresses) { - httpClient.checkAddressAvailable("/registry/microservices", null, null, address); + httpClient.checkAddressAvailable(address); } } } diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterDiscovery.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterDiscovery.java index 808c13daf3d..a1ab524c187 100644 --- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterDiscovery.java +++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterDiscovery.java @@ -17,12 +17,12 @@ package org.apache.servicecomb.service.center.client; -import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import org.apache.servicecomb.http.client.task.AbstractTask; @@ -101,6 +101,8 @@ public static class SubscriptionValue { private final Object lock = new Object(); + private final Random random = new Random(); + public ServiceCenterDiscovery(ServiceCenterClient serviceCenterClient, EventBus eventBus) { super("service-center-discovery-task"); this.serviceCenterClient = serviceCenterClient; @@ -153,13 +155,12 @@ public void onPullInstanceEvent(PullInstanceEvent event) { startTask(new PullInstanceOnceTask()); } - private List pullInstance(SubscriptionKey k, SubscriptionValue v, boolean sendChangedEvent) { + private void pullInstance(SubscriptionKey k, SubscriptionValue v, boolean sendChangedEvent) { if (myselfServiceId == null) { // registration not ready - return Collections.emptyList(); + return; } - List failedKeys = new ArrayList<>(); try { FindMicroserviceInstancesResponse instancesResponse = serviceCenterClient .findMicroserviceInstance(myselfServiceId, k.appId, k.serviceName, ALL_VERSION, v.revision); @@ -186,14 +187,9 @@ private List pullInstance(SubscriptionKey k, SubscriptionValue } } } catch (Exception e) { - LOGGER.warn("find service {}#{} instance failed.", k.appId, k.serviceName, e); - if (!(e.getCause() instanceof IOException)) { - // for IOException, do not remove cache, or when service center - // not available, invocation between microservices will fail. - failedKeys.add(k); - } + LOGGER.warn("find service {}#{} instance failed, remaining local instances cache [{}], cause message: {}", + k.appId, k.serviceName, instanceToString(v.instancesCache), e.getMessage()); } - return failedKeys; } private void setMicroserviceInfo(List instances) { @@ -216,10 +212,17 @@ class PullInstanceTask implements Task { public void execute() { pullAllInstance(); - startTask(new BackOffSleepTask(pollInterval, new PullInstanceTask())); + startTask(new BackOffSleepTask(buildPollIntervalWithSalt(), new PullInstanceTask())); } } + private long buildPollIntervalWithSalt() { + int positive = random.nextInt(5); + int sign = random.nextBoolean() ? 1 : -1; + long currentPollInterval = pollInterval + sign * positive * 1000; + return currentPollInterval > 0 ? currentPollInterval : pollInterval; + } + class PullInstanceOnceTask implements Task { @Override public void execute() { @@ -232,13 +235,15 @@ public void execute() { } private synchronized void pullAllInstance() { - List failedInstances = new ArrayList<>(); - instancesCache.forEach((k, v) -> failedInstances.addAll(pullInstance(k, v, true))); - if (failedInstances.isEmpty()) { - return; - } - failedInstances.forEach(instancesCache::remove); - failedInstances.clear(); + List emptyInstancesCache = new ArrayList<>(); + instancesCache.forEach((k, v) -> { + pullInstance(k, v, true); + if (v.instancesCache.isEmpty()) { + emptyInstancesCache.add(k); + } + }); + emptyInstancesCache.forEach(instancesCache::remove); + emptyInstancesCache.clear(); } private static String instanceToString(List instances) { @@ -252,6 +257,8 @@ private static String instanceToString(List instances) { sb.append(endpoint.length() > 64 ? endpoint.substring(0, 64) : endpoint); sb.append("|"); } + sb.append(instance.getStatus()); + sb.append("|"); } return sb.toString(); } diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterOperation.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterOperation.java index f296e66fae9..fd39a4ce963 100644 --- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterOperation.java +++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterOperation.java @@ -23,6 +23,7 @@ import org.apache.servicecomb.service.center.client.exception.OperationException; import org.apache.servicecomb.service.center.client.model.CreateSchemaRequest; import org.apache.servicecomb.service.center.client.model.FindMicroserviceInstancesResponse; +import org.apache.servicecomb.service.center.client.model.Framework; import org.apache.servicecomb.service.center.client.model.HeartbeatsRequest; import org.apache.servicecomb.service.center.client.model.Microservice; import org.apache.servicecomb.service.center.client.model.MicroserviceInstance; @@ -159,7 +160,6 @@ boolean updateMicroserviceInstanceStatus(String serviceId, String instanceId, * Batch send heartbeats to service-center * * @param heartbeatsRequest - * @return * @throws OperationException */ void sendHeartBeats(HeartbeatsRequest heartbeatsRequest); @@ -184,7 +184,7 @@ boolean updateMicroserviceInstanceStatus(String serviceId, String instanceId, * @return if heartbeat is successful * @throws OperationException If some problems happened to contact service center or non http 200 returned. */ - RbacTokenResponse queryToken(RbacTokenRequest request); + RbacTokenResponse queryToken(RbacTokenRequest request, String host); /** * Update properties of microservice @@ -192,7 +192,8 @@ boolean updateMicroserviceInstanceStatus(String serviceId, String instanceId, * @return if update is successful * @throws OperationException If some problems happened to contact service center or non http 200 returned. */ - boolean updateMicroserviceProperties(String microserviceId, Map serviceProperties); + boolean updateMicroserviceProperties(String microserviceId, Map serviceProperties, + Framework framework); /** * Check serviceCenter isolation address available diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java index e95240bb3c5..e233f15fb52 100755 --- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java +++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java @@ -21,23 +21,33 @@ import java.util.HashMap; import java.util.Map; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpStatus; import org.apache.servicecomb.http.client.common.HttpRequest; import org.apache.servicecomb.http.client.common.HttpResponse; import org.apache.servicecomb.http.client.common.HttpTransport; +import org.apache.servicecomb.http.client.event.OperationEvents.UnAuthorizedOperationEvent; +import org.apache.servicecomb.http.client.utils.ServiceCombServiceAvailableUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.eventbus.EventBus; + public class ServiceCenterRawClient { private static final Logger LOGGER = LoggerFactory.getLogger(ServiceCenterRawClient.class); private static final String HEADER_TENANT_NAME = "x-domain-name"; + private static final String ADDRESS_CHECK_PATH = "/v4/default/registry/health/readiness"; + private final String tenantName; private final HttpTransport httpTransport; private final ServiceCenterAddressManager addressManager; + private EventBus eventBus; + private ServiceCenterRawClient(String tenantName, HttpTransport httpTransport, ServiceCenterAddressManager addressManager) { this.httpTransport = httpTransport; @@ -45,37 +55,40 @@ private ServiceCenterRawClient(String tenantName, HttpTransport httpTransport, this.addressManager = addressManager; } + public void setEventBus(EventBus eventBus) { + this.eventBus = eventBus; + } + public HttpResponse getHttpRequest(String url, Map headers, String content) throws IOException { - return doHttpRequest(url, false, headers, content, HttpRequest.GET); + return doHttpRequest(url, false, headers, content, HttpRequest.GET, ""); } - public HttpResponse postHttpRequestAbsoluteUrl(String url, Map headers, String content) - throws IOException { - return doHttpRequest(url, true, headers, content, HttpRequest.POST); + public HttpResponse postHttpRequestAbsoluteUrl(String url, Map headers, String content, + String address) throws IOException { + return doHttpRequest(url, true, headers, content, HttpRequest.POST, address); } public HttpResponse postHttpRequest(String url, Map headers, String content) throws IOException { - return doHttpRequest(url, false, headers, content, HttpRequest.POST); + return doHttpRequest(url, false, headers, content, HttpRequest.POST, ""); } public HttpResponse putHttpRequest(String url, Map headers, String content) throws IOException { - return doHttpRequest(url, false, headers, content, HttpRequest.PUT); + return doHttpRequest(url, false, headers, content, HttpRequest.PUT, ""); } public HttpResponse deleteHttpRequest(String url, Map headers, String content) throws IOException { - return doHttpRequest(url, false, headers, content, HttpRequest.DELETE); + return doHttpRequest(url, false, headers, content, HttpRequest.DELETE, ""); } private HttpResponse doHttpRequest(String url, boolean absoluteUrl, Map headers, String content, - String method) - throws IOException { - String address = addressManager.address(); + String method, String queryAddress) throws IOException { + String address = StringUtils.isEmpty(queryAddress) ? addressManager.address() : queryAddress; String formatUrl = addressManager.formatUrl(url, absoluteUrl, address); HttpRequest httpRequest = buildHttpRequest(formatUrl, headers, content, method); - + HttpResponse httpResponse; try { - HttpResponse httpResponse = httpTransport.doRequest(httpRequest); - addressManager.recordSuccessState(address); + httpResponse = httpTransport.doRequest(httpRequest); + recordAndSendUnAuthorizedEvent(httpResponse, address); return httpResponse; } catch (IOException e) { addressManager.recordFailState(address); @@ -84,7 +97,9 @@ private HttpResponse doHttpRequest(String url, boolean absoluteUrl, Map headers, String content, - String address) { - String formatUrl = addressManager.formatUrl(url, false, address); - HttpRequest httpRequest = buildHttpRequest(formatUrl, headers, content, HttpRequest.GET); - try { - httpTransport.doRequest(httpRequest); - addressManager.recoverIsolatedAddress(address); - } catch (IOException e) { - LOGGER.error("check service center isolation address {} available error!", address); + private void recordAndSendUnAuthorizedEvent(HttpResponse response, String address) { + if (this.eventBus != null && response.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { + LOGGER.warn("request unauthorized from server [{}], message [{}]", address, response.getMessage()); + addressManager.recordFailState(address); + this.eventBus.post(new UnAuthorizedOperationEvent(address)); + } else { + addressManager.recordSuccessState(address); } } + public void checkAddressAvailable(String address) { + ServiceCombServiceAvailableUtils.checkAddressAvailable(addressManager, address, httpTransport, ADDRESS_CHECK_PATH); + } + private HttpRequest buildHttpRequest(String url, Map headers, String content, String method) { if (headers == null) { headers = new HashMap<>(); diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRegistration.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRegistration.java index 3f455250270..93988ea8948 100644 --- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRegistration.java +++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRegistration.java @@ -148,13 +148,13 @@ public void execute() { microservice.setProperties(newMicroservice.getProperties()); microservice.getProperties().putAll(propertiesTemp); if (serviceCenterClient.updateMicroserviceProperties(serviceResponse.getServiceId(), - microservice.getProperties())) { + microservice.getProperties(), microservice.getFramework())) { LOGGER.info( - "microservice is already registered. Update microservice properties successfully. properties=[{}]", - microservice.getProperties()); + "microservice is already registered. Update microservice properties successfully. properties=[{}], " + + "frameworkVersion [{}]", microservice.getProperties(), microservice.getFramework().getVersion()); } else { - LOGGER.error("microservice is already registered. Update microservice properties failed. properties=[{}]", - microservice.getProperties()); + LOGGER.error("microservice is already registered. Update microservice properties failed. properties=[{}], " + + "frameworkVersion [{}]", microservice.getProperties(), microservice.getFramework().getVersion()); } microservice.setServiceId(serviceResponse.getServiceId()); @@ -287,7 +287,7 @@ public void execute() { } if (!serviceCenterClient.sendHeartBeat(microservice.getServiceId(), microserviceInstance.getInstanceId())) { - LOGGER.error("send heart failed, and will try again."); + LOGGER.warn("send heart failed, and will try again."); eventBus.post(new HeartBeatEvent(false, microservice, microserviceInstance)); startTask(new BackOffSleepTask(failedCount + 1, new SendHeartBeatTask(failedCount + 1))); } else { @@ -297,7 +297,12 @@ public void execute() { new BackOffSleepTask(Math.max(heartBeatInterval, heartBeatRequestTimeout), new SendHeartBeatTask(0))); } } catch (Exception e) { - LOGGER.error("send heart failed, and will try again.", e); + // If heartbeat failures three times, log error stack help troubleshooting. Others just log message as warn. + if (failedCount == 2) { + LOGGER.error("send heart failed, and will try again.", e); + } else { + LOGGER.warn("send heart failed, and will try again. message [{}]", e.getMessage()); + } eventBus.post(new HeartBeatEvent(false, microservice, microserviceInstance)); startTask(new BackOffSleepTask(failedCount + 1, new SendHeartBeatTask(failedCount + 1))); } diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterWatch.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterWatch.java index a8be8b98b78..9f24a74a55a 100644 --- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterWatch.java +++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterWatch.java @@ -17,12 +17,15 @@ package org.apache.servicecomb.service.center.client; +import java.net.URI; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.servicecomb.foundation.auth.SignRequest; import org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider; import org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties; import org.apache.servicecomb.http.client.common.WebSocketListener; @@ -67,7 +70,7 @@ public class ServiceCenterWatch implements WebSocketListener { private String serviceId; - private int continuousError = 0; + private AtomicInteger continuousError = new AtomicInteger(0); private final AtomicBoolean reconnecting = new AtomicBoolean(false); @@ -107,7 +110,7 @@ private void startWatch() { Map headers = new HashMap<>(); headers.put("x-domain-name", this.tenantName); headers.putAll(this.extraGlobalHeaders); - headers.putAll(this.requestAuthHeaderProvider.loadAuthHeader(null)); + headers.putAll(this.requestAuthHeaderProvider.loadAuthHeader(createSignRequest(address))); currentServerUri = convertAddress(address); LOGGER.info("start watch to address {}", currentServerUri); webSocketTransport = new WebSocketTransport(currentServerUri, sslProperties, @@ -121,6 +124,17 @@ private void startWatch() { }); } + private SignRequest createSignRequest(String url) { + try { + URI uri = URI.create(url); + SignRequest signRequest = new SignRequest(); + signRequest.setEndpoint(uri); + return signRequest; + } catch (Exception e) { + return null; + } + } + private String convertAddress(String address) { String url = String.format(WATCH, project, serviceId); if (address.startsWith(HTTP)) { @@ -143,7 +157,7 @@ private void reconnect() { if (reconnecting.getAndSet(true)) { return; } - continuousError++; + continuousError.incrementAndGet(); if (webSocketTransport != null) { webSocketTransport.close(); } @@ -151,11 +165,11 @@ private void reconnect() { } private void backOff() { - if (this.continuousError <= 0) { + if (this.continuousError.get() <= 0) { return; } try { - Thread.sleep(Math.min(SLEEP_MAX, this.continuousError * this.continuousError * SLEEP_BASE)); + Thread.sleep(Math.min(SLEEP_MAX, this.continuousError.get() * this.continuousError.get() * SLEEP_BASE)); } catch (InterruptedException e) { // do not care } @@ -183,7 +197,7 @@ public void onOpen(ServerHandshake serverHandshake) { LOGGER.info("web socket connected to server {}, status={}, message={}", currentServerUri, serverHandshake.getHttpStatus(), serverHandshake.getHttpStatusMessage()); - continuousError = 0; + continuousError.set(0); reconnecting.set(false); } } diff --git a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/UpdatePropertiesRequest.java b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/UpdatePropertiesRequest.java index b10586208a8..d7d4b093930 100644 --- a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/UpdatePropertiesRequest.java +++ b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/model/UpdatePropertiesRequest.java @@ -22,6 +22,8 @@ public class UpdatePropertiesRequest { private Map properties; + private Framework framework; + public Map getProperties() { return properties; } @@ -29,4 +31,12 @@ public Map getProperties() { public void setProperties(Map properties) { this.properties = properties; } + + public Framework getFramework() { + return framework; + } + + public void setFramework(Framework framework) { + this.framework = framework; + } } diff --git a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManagerTest.java b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManagerTest.java index f5c316cd848..a2888cfad1b 100644 --- a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManagerTest.java +++ b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManagerTest.java @@ -41,7 +41,7 @@ class ServiceCenterAddressManagerTest { @Test public void getUrlPrefix() { addresses.add("http://127.0.0.1:30103"); - addressManager1 = new ServiceCenterAddressManager("project", addresses, new EventBus()); + addressManager1 = new ServiceCenterAddressManager("project", addresses, new EventBus(), "", ""); Assertions.assertNotNull(addressManager1); @@ -55,7 +55,7 @@ public void getUrlPrefix() { @Test public void formatUrlTest() { addresses.add("http://127.0.0.1:30103"); - addressManager1 = new ServiceCenterAddressManager("project", addresses, new EventBus()); + addressManager1 = new ServiceCenterAddressManager("project", addresses, new EventBus(), "", ""); Assertions.assertNotNull(addressManager1); String address = addressManager1.address(); @@ -76,7 +76,7 @@ public void onRefreshEndpointEvent() { Map> zoneAndRegion = new HashMap<>(); zoneAndRegion.put("sameZone", addressAZ); zoneAndRegion.put("sameRegion", addressRG); - addressManager1 = new ServiceCenterAddressManager("project", addresses, new EventBus()); + addressManager1 = new ServiceCenterAddressManager("project", addresses, new EventBus(), "", ""); RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, "SERVICECENTER"); addressManager1.refreshEndpoint(event, "SERVICECENTER"); diff --git a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterClientTest.java b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterClientTest.java index 12ad9cda3ab..c486b2bd6ce 100755 --- a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterClientTest.java +++ b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterClientTest.java @@ -19,10 +19,12 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import org.apache.servicecomb.http.client.common.HttpResponse; +import org.apache.servicecomb.service.center.client.model.Framework; import org.apache.servicecomb.service.center.client.model.HeartbeatsRequest; import org.apache.servicecomb.service.center.client.model.InstancesRequest; import org.apache.servicecomb.service.center.client.model.Microservice; @@ -41,11 +43,18 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; +import com.google.common.eventbus.EventBus; /** * Created by on 2019/10/17. */ public class ServiceCenterClientTest { + private final ServiceCenterAddressManager addressManager; + + public ServiceCenterClientTest() { + this.addressManager = new ServiceCenterAddressManager("default", Arrays.asList("http://127.0.0.1:30100"), + new EventBus(), "", ""); + } @Test public void TestGetServiceCenterInstances() throws IOException { @@ -92,7 +101,7 @@ public void TestGetServiceCenterInstances() throws IOException { Mockito.when(serviceCenterRawClient.getHttpRequest("/registry/health", null, null)).thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); MicroserviceInstancesResponse serviceCenterInstances = serviceCenterClient.getServiceCenterInstances(); Assertions.assertNotNull(serviceCenterInstances); @@ -121,7 +130,7 @@ public void TestRegistryService() throws IOException { Mockito.anyString())) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); RegisteredMicroserviceResponse actualResponse = serviceCenterClient.registerMicroservice(microservice); Assertions.assertNotNull(actualResponse); @@ -179,7 +188,7 @@ public void TestGetServiceMessage() throws IOException { Mockito.when(serviceCenterRawClient.getHttpRequest("/registry/microservices/111111", null, null)) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); Microservice microservices = serviceCenterClient.getMicroserviceByServiceId("111111"); Assertions.assertNotNull(microservices); @@ -207,7 +216,7 @@ public void TestGetServiceList() throws IOException { Mockito.when(serviceCenterRawClient.getHttpRequest(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); MicroservicesResponse actualMicroservicesResponse = serviceCenterClient.getMicroserviceList(); Assertions.assertNotNull(actualMicroservicesResponse); @@ -228,7 +237,7 @@ public void TestQueryServiceId() throws IOException { Mockito.when(serviceCenterRawClient.getHttpRequest(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); Microservice microservice = new Microservice("Test111"); RegisteredMicroserviceResponse actualServiceId = serviceCenterClient.queryServiceId(microservice); @@ -257,7 +266,7 @@ public void TestRegisterServiceInstance() throws IOException { Mockito.anyString())) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); RegisteredMicroserviceInstanceResponse actualResponse = serviceCenterClient.registerMicroserviceInstance(instance); Assertions.assertNotNull(actualResponse); @@ -276,7 +285,7 @@ public void TestDeleteServiceInstance() throws IOException { Mockito.when(serviceCenterRawClient.deleteHttpRequest(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); serviceCenterClient.deleteMicroserviceInstance("111", "222"); } @@ -310,7 +319,7 @@ public void TestGetServiceInstanceList() throws IOException { Mockito.when(serviceCenterRawClient.getHttpRequest("/registry/microservices/222222/instances", null, null)) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); MicroserviceInstancesResponse serviceCenterInstances = serviceCenterClient .getMicroserviceInstanceList("222222"); @@ -364,7 +373,7 @@ public void TestGetServiceInstanceMessage() throws IOException { Mockito.when(serviceCenterRawClient.getHttpRequest(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); MicroserviceInstance responseInstance = serviceCenterClient .getMicroserviceInstance("111", "222"); @@ -394,7 +403,7 @@ public void TestSendHeartBeats() throws IOException { Mockito.anyString())) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); serviceCenterClient.sendHeartBeats(heartbeatsRequest); } @@ -410,7 +419,7 @@ public void TestUpdateServicesInstanceStatus() throws IOException { Mockito.when(serviceCenterRawClient.putHttpRequest(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); Boolean result = serviceCenterClient .updateMicroserviceInstanceStatus("111", "222", MicroserviceInstanceStatus.UP); @@ -440,7 +449,7 @@ public void TestGetServiceSchemas() throws IOException { Mockito.when(serviceCenterRawClient.getHttpRequest(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); List schemaResponse = serviceCenterClient .getServiceSchemasList("111", false); @@ -468,7 +477,7 @@ public void TestGetServiceSchemasContext() throws IOException { Mockito.when(serviceCenterRawClient.getHttpRequest(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); String schemaContext = serviceCenterClient .getServiceSchemaContext("111", "222"); @@ -488,7 +497,7 @@ public void TestUpdateServiceSchema() throws IOException { Mockito.when(serviceCenterRawClient.putHttpRequest(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); boolean result = serviceCenterClient .updateServiceSchemaContext("111", new SchemaInfo()); @@ -506,9 +515,9 @@ public void testUpdateMicroserviceProperties() throws IOException { Mockito.when(serviceCenterRawClient.putHttpRequest(Mockito.any(), Mockito.any(), Mockito.any())) .thenReturn(httpResponse); - ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient); + ServiceCenterClient serviceCenterClient = new ServiceCenterClient(serviceCenterRawClient, addressManager); boolean result = serviceCenterClient - .updateMicroserviceProperties("111", new HashMap()); + .updateMicroserviceProperties("111", new HashMap(), new Framework()); Assertions.assertTrue(result); } diff --git a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClientTest.java b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClientTest.java index 29337e31a44..48f3bd914c6 100755 --- a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClientTest.java +++ b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClientTest.java @@ -41,7 +41,8 @@ public class ServiceCenterRawClientTest { public void TestDefaultParameter() throws IOException { HttpTransport httpTransport = Mockito.mock(HttpTransport.class); - ServiceCenterAddressManager addressManager = new ServiceCenterAddressManager(PROJECT_NAME, Arrays.asList("http://127.0.0.1:30100"), new EventBus()); + ServiceCenterAddressManager addressManager = new ServiceCenterAddressManager(PROJECT_NAME, + Arrays.asList("http://127.0.0.1:30100"), new EventBus(), "", ""); ServiceCenterRawClient client = new ServiceCenterRawClient.Builder() .setHttpTransport(httpTransport) .setAddressManager(addressManager) diff --git a/common/common-access-log/pom.xml b/common/common-access-log/pom.xml index b4f05f2eb6b..e572e6bfd94 100644 --- a/common/common-access-log/pom.xml +++ b/common/common-access-log/pom.xml @@ -21,7 +21,7 @@ common org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/RequestHeaderItemTest.java b/common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/RequestHeaderItemTest.java index 77a807c32a2..f2ae7004251 100644 --- a/common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/RequestHeaderItemTest.java +++ b/common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/RequestHeaderItemTest.java @@ -78,7 +78,7 @@ public void initStrBuilder() { @Test public void serverFormattedElement() { - HeadersMultiMap headers = new HeadersMultiMap(); + HeadersMultiMap headers = HeadersMultiMap.httpHeaders(); String testValue = "testValue"; headers.add(VAR_NAME, testValue); when(routingContext.request()).thenReturn(serverRequest); @@ -129,7 +129,7 @@ public void clientFormattedElementIfHeaderIsNull() { @Test public void serverFormattedElementIfNotFound() { - HeadersMultiMap headers = new HeadersMultiMap(); + HeadersMultiMap headers = HeadersMultiMap.httpHeaders(); String testValue = "testValue"; headers.add("anotherKey", testValue); when(routingContext.request()).thenReturn(serverRequest); diff --git a/common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/ResponseHeaderItemTest.java b/common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/ResponseHeaderItemTest.java index a2e283e4bc8..a8708172945 100644 --- a/common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/ResponseHeaderItemTest.java +++ b/common/common-access-log/src/test/java/org/apache/servicecomb/common/accessLog/core/element/impl/ResponseHeaderItemTest.java @@ -64,7 +64,7 @@ public void initStrBuilder() { @Test public void serverFormattedElement() { - HeadersMultiMap headers = new HeadersMultiMap(); + HeadersMultiMap headers = HeadersMultiMap.httpHeaders(); String headerValue = "headerValue"; headers.add(VAR_NAME, headerValue); when(routingContext.response()).thenReturn(serverResponse); @@ -122,7 +122,7 @@ public void clientFormattedElementOnResponseIsNull() { @Test public void serverFormattedElementOnNotFound() { - HeadersMultiMap headers = new HeadersMultiMap(); + HeadersMultiMap headers = HeadersMultiMap.httpHeaders(); String headerValue = "headerValue"; headers.add("anotherHeader", headerValue); when(routingContext.response()).thenReturn(serverResponse); diff --git a/common/common-protobuf/pom.xml b/common/common-protobuf/pom.xml index 3297dc0cba3..5b7ac5fcf7c 100644 --- a/common/common-protobuf/pom.xml +++ b/common/common-protobuf/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb common - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT common-protobuf Java Chassis::Common::Protobuf diff --git a/common/common-rest/pom.xml b/common/common-rest/pom.xml index 7ee481309de..f1f2c84b45b 100644 --- a/common/common-rest/pom.xml +++ b/common/common-rest/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb common - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT common-rest diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecMulti.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecMulti.java index 551ccee01ae..4c2f4287916 100644 --- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecMulti.java +++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/query/QueryCodecMulti.java @@ -25,9 +25,6 @@ import jakarta.servlet.http.HttpServletRequest; -/** - * ?query=x1&query=x2 - */ @SuppressWarnings("unchecked") public class QueryCodecMulti extends AbstractQueryCodec { public static final String CODEC_NAME = "form:1"; diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java index 6b2e3b3324f..580175ec680 100644 --- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java +++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java @@ -102,7 +102,7 @@ public void init(OperationMeta operationMeta) { } } - setAbsolutePath(concatPath(SwaggerUtils.getBasePath(swagger), operationMeta.getOperationPath())); + setAbsolutePath(SwaggerUtils.concatAbsolutePath(swagger, operationMeta.getOperationPath())); } private void addRestParamByName(OperationMeta operationMeta, String name, Operation operation) { @@ -168,21 +168,6 @@ public void setOperationMeta(OperationMeta operationMeta) { this.operationMeta = operationMeta; } - /** - * Concat the two paths to an absolute path, end of '/' added. - * - * e.g. "/" + "/ope" = /ope/ - * e.g. "/prefix" + "/ope" = /prefix/ope/ - */ - private String concatPath(String basePath, String operationPath) { - return ("/" + nonNullify(basePath) + "/" + nonNullify(operationPath)) - .replaceAll("/{2,}", "/"); - } - - private String nonNullify(String path) { - return path == null ? "" : path; - } - public String getAbsolutePath() { return this.absolutePath; } diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessor.java index 784150324e8..ab71e3a9e99 100644 --- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessor.java +++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessor.java @@ -116,7 +116,7 @@ public void before() { LegacyPropertyFactory.setEnvironment(environment); Mockito.when(environment.getProperty("servicecomb.rest.parameter.decodeAsObject", boolean.class, false)) .thenReturn(false); - headers = new HeadersMultiMap(); + headers = HeadersMultiMap.httpHeaders(); value = "value"; } diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/resource/TestClassPathStaticResourceHandler.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/resource/TestClassPathStaticResourceHandler.java index 3055b3751bb..f95468f4f38 100644 --- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/resource/TestClassPathStaticResourceHandler.java +++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/resource/TestClassPathStaticResourceHandler.java @@ -20,10 +20,6 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; -import jakarta.servlet.http.Part; -import jakarta.ws.rs.core.HttpHeaders; -import jakarta.ws.rs.core.Response.Status; - import org.apache.commons.io.IOUtils; import org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace; import org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector; @@ -35,6 +31,10 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import jakarta.servlet.http.Part; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.Response.Status; + public class TestClassPathStaticResourceHandler { static ClassPathStaticResourceHandler handler = new ClassPathStaticResourceHandler(); @@ -49,7 +49,7 @@ public void normal() throws IOException { Part part = response.getResult(); try (InputStream is = part.getInputStream()) { - Assertions.assertTrue(IOUtils.toString(is, StandardCharsets.UTF_8).endsWith("\n")); + Assertions.assertTrue(IOUtils.toString(is, StandardCharsets.UTF_8).trim().endsWith("")); } Assertions.assertEquals("text/html", part.getContentType()); Assertions.assertEquals("text/html", response.getHeader(HttpHeaders.CONTENT_TYPE)); @@ -84,7 +84,7 @@ public void attack() { public void readContentFailed() throws IOException { handler = Mockito.spy(TestClassPathStaticResourceHandler.handler); Mockito.when(handler.findResource("web-root/index.html")) - .thenThrow(new RuntimeExceptionWithoutStackTrace("read content failed.")); + .thenThrow(new RuntimeExceptionWithoutStackTrace("read content failed.")); try (LogCollector logCollector = new LogCollector()) { Response response = handler.handle("index.html"); diff --git a/common/pom.xml b/common/pom.xml index 1b42907ba61..c39c89ff4ce 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default common diff --git a/core/pom.xml b/core/pom.xml index 63245883d41..af73c36dff9 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default java-chassis-core diff --git a/core/src/main/java/org/apache/servicecomb/core/BootListener.java b/core/src/main/java/org/apache/servicecomb/core/BootListener.java index 507b3e32d43..ea8314e2e1d 100644 --- a/core/src/main/java/org/apache/servicecomb/core/BootListener.java +++ b/core/src/main/java/org/apache/servicecomb/core/BootListener.java @@ -115,14 +115,6 @@ default void onBootEvent(BootEvent event) { } } - default void onBeforeHandler(BootEvent event) { - - } - - default void onAfterHandler(BootEvent event) { - - } - default void onBeforeFilter(BootEvent event) { } diff --git a/core/src/main/java/org/apache/servicecomb/core/Invocation.java b/core/src/main/java/org/apache/servicecomb/core/Invocation.java index 6bb00703995..067fe6558f4 100644 --- a/core/src/main/java/org/apache/servicecomb/core/Invocation.java +++ b/core/src/main/java/org/apache/servicecomb/core/Invocation.java @@ -84,15 +84,15 @@ static Collection loadTraceIdGenerators() { // 同步模式:避免应答在网络线程中处理解码等等业务级逻辑 private Executor responseExecutor; - private boolean sync = true; + private volatile boolean sync = true; private final InvocationStageTrace invocationStageTrace = new InvocationStageTrace(this); private HttpServletRequestEx requestEx; - private boolean finished; + private volatile boolean finished; - private long invocationId; + private volatile long invocationId; private TraceIdLogger traceIdLogger; diff --git a/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java b/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java index 2d8b86818c6..c69521698af 100644 --- a/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java +++ b/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java @@ -370,8 +370,6 @@ private void doRun() throws Exception { triggerEvent(EventType.BEFORE_REGISTRY); registrationManager.run(); discoveryManager.run(); - // ensure can invoke services in AFTER_REGISTRY - registrationManager.updateMicroserviceInstanceStatus(MicroserviceInstanceStatus.UP); status = SCBStatus.UP; triggerEvent(EventType.AFTER_REGISTRY); diff --git a/core/src/main/java/org/apache/servicecomb/core/executor/GroupExecutor.java b/core/src/main/java/org/apache/servicecomb/core/executor/GroupExecutor.java index 24e41d407cd..13562914fac 100644 --- a/core/src/main/java/org/apache/servicecomb/core/executor/GroupExecutor.java +++ b/core/src/main/java/org/apache/servicecomb/core/executor/GroupExecutor.java @@ -100,7 +100,7 @@ public GroupExecutor init(String groupName) { return this; } - public void initConfig() { + public synchronized void initConfig() { if (LOG_PRINTED.compareAndSet(false, true)) { LOGGER.info("thread pool rules:\n" + "1.use core threads.\n" diff --git a/core/src/main/java/org/apache/servicecomb/core/governance/MatchType.java b/core/src/main/java/org/apache/servicecomb/core/governance/MatchType.java index 2c100670630..15d58d66610 100644 --- a/core/src/main/java/org/apache/servicecomb/core/governance/MatchType.java +++ b/core/src/main/java/org/apache/servicecomb/core/governance/MatchType.java @@ -36,7 +36,7 @@ private GovernanceRequestExtractorImpl(Invocation invocation) { public String apiPath() { if (MatchType.REST.equalsIgnoreCase(invocation.getOperationMeta().getConfig().getGovernanceMatchType())) { if (!invocation.isProducer()) { - return concatAbsolutePath(SwaggerUtils.getBasePath(invocation.getSchemaMeta().getSwagger()), + return SwaggerUtils.concatAbsolutePath(invocation.getSchemaMeta().getSwagger(), invocation.getOperationMeta().getOperationPath()); } // not highway @@ -114,19 +114,4 @@ public Object sourceRequest() { public static GovernanceRequestExtractor createGovHttpRequest(Invocation invocation) { return new GovernanceRequestExtractorImpl(invocation); } - - /** - * Concat the two paths to an absolute path, without end of '/'. - * - * e.g. "/" + "/ope" = /ope - * e.g. "/prefix" + "/ope" = /prefix/ope - */ - private static String concatAbsolutePath(String basePath, String operationPath) { - return ("/" + nonNullify(basePath) + "/" + nonNullify(operationPath)) - .replaceAll("/{2,}", "/"); - } - - private static String nonNullify(String path) { - return path == null ? "" : path; - } } diff --git a/core/src/main/java/org/apache/servicecomb/core/invocation/endpoint/EndpointUtils.java b/core/src/main/java/org/apache/servicecomb/core/invocation/endpoint/EndpointUtils.java index d906de63ba5..2d8b37c997a 100644 --- a/core/src/main/java/org/apache/servicecomb/core/invocation/endpoint/EndpointUtils.java +++ b/core/src/main/java/org/apache/servicecomb/core/invocation/endpoint/EndpointUtils.java @@ -88,7 +88,7 @@ public static Endpoint parse(String uriEndpoint) { } /** - *
+   * {@code
    *   http://xxx  -> rest://xxx
    *   https://xxx -> rest://xxx?sslEnabled=true
    *
@@ -98,7 +98,7 @@ public static Endpoint parse(String uriEndpoint) {
    *   xxx         -> rest://xxx:port?protocol=http2
    *   xxx?a=a1    -> rest://xxx:port?a=a1&protocol=http2
    *   other://xxx -> other://xxx
-   * 
+ * } * * This method provided for convenience of handling user input endpoints, and do not have a strict meaning. Make sure all unit test cases * work before change. diff --git a/core/src/test/java/org/apache/servicecomb/core/TestInvocation.java b/core/src/test/java/org/apache/servicecomb/core/TestInvocation.java index 4cf335cd34c..80b6bbda461 100644 --- a/core/src/test/java/org/apache/servicecomb/core/TestInvocation.java +++ b/core/src/test/java/org/apache/servicecomb/core/TestInvocation.java @@ -17,7 +17,6 @@ package org.apache.servicecomb.core; import java.util.Arrays; -import java.util.Map; import org.apache.servicecomb.core.definition.InvocationRuntimeType; import org.apache.servicecomb.core.definition.OperationMeta; @@ -49,7 +48,6 @@ import mockit.Mocked; public class TestInvocation { - Invocation invocation; @Mocked Endpoint endpoint; @@ -60,9 +58,6 @@ public class TestInvocation { @Mocked InvocationRuntimeType invocationRuntimeType; - @Mocked - Map arguments; - static long nanoTime = 123; @BeforeClass @@ -95,7 +90,7 @@ public void onStart(InvocationStartEvent event) { }; EventManager.register(subscriber); - Invocation invocation = new Invocation(endpoint, operationMeta, arguments); + Invocation invocation = new Invocation(endpoint, operationMeta, null); invocation.onStart(); Assertions.assertSame(invocation, result.value); @@ -115,7 +110,7 @@ public void onStart(InvocationFinishEvent event) { }; EventManager.register(subscriber); - Invocation invocation = new Invocation(endpoint, operationMeta, arguments); + Invocation invocation = new Invocation(endpoint, operationMeta, null); Assertions.assertFalse(invocation.isFinished()); Response response = Response.succResp(null); invocation.onFinish(response); @@ -134,19 +129,19 @@ public void onStart(InvocationFinishEvent event) { @Test public void isConsumer_yes() { - Invocation invocation = new Invocation(endpoint, operationMeta, arguments); + Invocation invocation = new Invocation(endpoint, operationMeta, null); Assertions.assertFalse(invocation.isConsumer()); } @Test public void isConsumer_no(@Mocked ReferenceConfig referenceConfig) { - Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, arguments); + Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, null); Assertions.assertTrue(invocation.isConsumer()); } @Test public void localContext(@Mocked ReferenceConfig referenceConfig) { - Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, arguments); + Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, null); invocation.addLocalContext("k", 1); Assertions.assertSame(invocation.getHandlerContext(), invocation.getLocalContext()); @@ -155,7 +150,7 @@ public void localContext(@Mocked ReferenceConfig referenceConfig) { @Test public void traceId_fromContext(@Mocked ReferenceConfig referenceConfig) { - Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, arguments); + Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, null); invocation.addContext(CoreConst.TRACE_ID_NAME, "abc"); invocation.onStart(); @@ -173,7 +168,7 @@ public void traceId_consumerCreateTraceId(@Mocked ReferenceConfig referenceConfi result = "abc"; } }; - Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, arguments); + Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, null); invocation.onStart(); @@ -189,7 +184,7 @@ public void traceId_fromRequest(@Mocked Endpoint endpoint, @Mocked HttpServletRe result = "abc"; } }; - Invocation invocation = new Invocation(endpoint, operationMeta, arguments); + Invocation invocation = new Invocation(endpoint, operationMeta, null); invocation.onStart(requestEx); @@ -199,6 +194,7 @@ public void traceId_fromRequest(@Mocked Endpoint endpoint, @Mocked HttpServletRe @Test public void traceId_producerCreateTraceId(@Mocked Endpoint endpoint, @Mocked HttpServletRequestEx requestEx) { + TraceIdGenerator generator = SPIServiceUtils.getTargetService(TraceIdGenerator.class, BraveTraceIdGenerator.class); new Expectations(generator) { { @@ -206,7 +202,7 @@ public void traceId_producerCreateTraceId(@Mocked Endpoint endpoint, @Mocked Htt result = "abc"; } }; - Invocation invocation = new Invocation(endpoint, operationMeta, arguments); + Invocation invocation = new Invocation(endpoint, operationMeta, null); invocation.onStart(requestEx); @@ -250,7 +246,7 @@ public void onBusinessMethodStart(InvocationBusinessMethodStartEvent event) { } }; EventManager.getEventBus().register(listener); - Invocation invocation = new Invocation(endpoint, operationMeta, arguments); + Invocation invocation = new Invocation(endpoint, operationMeta, null); mockNonaTime(); invocation.onBusinessMethodStart(); EventManager.getEventBus().unregister(listener); @@ -265,12 +261,12 @@ public void onBusinessMethodStart(InvocationBusinessMethodStartEvent event) { public void marker(@Mocked ReferenceConfig referenceConfig) { Invocation.INVOCATION_ID.set(0); - Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, arguments); + Invocation invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, null); invocation.addContext(CoreConst.TRACE_ID_NAME, "abc"); invocation.onStart(); Assertions.assertEquals("abc", invocation.getTraceIdLogger().getName()); - invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, arguments); + invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, null); invocation.addContext(CoreConst.TRACE_ID_NAME, "abc"); invocation.onStart(); Assertions.assertEquals("abc", invocation.getTraceIdLogger().getName()); diff --git a/core/src/test/java/org/apache/servicecomb/core/executor/TestGroupExecutor.java b/core/src/test/java/org/apache/servicecomb/core/executor/TestGroupExecutor.java index d92ca3bb2ce..dd95105992b 100644 --- a/core/src/test/java/org/apache/servicecomb/core/executor/TestGroupExecutor.java +++ b/core/src/test/java/org/apache/servicecomb/core/executor/TestGroupExecutor.java @@ -111,7 +111,7 @@ public void maxThreads() { Assertions.assertEquals( "servicecomb.executor.default.thread-per-group is deprecated, recommended to use servicecomb.executor.default.maxThreads-per-group.", collector.getEvents().get(collector.getEvents().size() - 2).getMessage().getFormattedMessage()); - collector.teardown(); + collector.tearDown(); Mockito.when(environment.getProperty(KEY_MAX_THREADS, int.class, -1)).thenReturn(300); groupExecutor.initConfig(); @@ -127,7 +127,7 @@ public void adjustCoreThreads() { Assertions.assertEquals( "coreThreads is bigger than maxThreads, change from 25 to 10.", collector.getEvents().get(collector.getEvents().size() - 2).getMessage().getFormattedMessage()); - collector.teardown(); + collector.tearDown(); } @Test diff --git a/core/src/test/java/org/apache/servicecomb/core/filter/impl/ProducerOperationFilterTest.java b/core/src/test/java/org/apache/servicecomb/core/filter/impl/ProducerOperationFilterTest.java index 4531895e9b2..dd46b17d28b 100644 --- a/core/src/test/java/org/apache/servicecomb/core/filter/impl/ProducerOperationFilterTest.java +++ b/core/src/test/java/org/apache/servicecomb/core/filter/impl/ProducerOperationFilterTest.java @@ -189,8 +189,7 @@ public void should_unify_IllegalArgumentException_message_when_convert_exception assertThat(future) .failsWithin(Duration.ofSeconds(1)) .withThrowableOfType(ExecutionException.class) - .withCauseExactlyInstanceOf(IllegalArgumentException.class) - .withMessage("java.lang.IllegalArgumentException: wrong number of arguments"); + .withCauseExactlyInstanceOf(IllegalArgumentException.class); InvocationException throwable = Exceptions .convert(invocation, catchThrowable(future::get), INTERNAL_SERVER_ERROR); diff --git a/core/src/test/java/org/apache/servicecomb/core/invocation/endpoint/EndpointTest.java b/core/src/test/java/org/apache/servicecomb/core/invocation/endpoint/EndpointTest.java index a28a2be4208..b3c0733bb48 100644 --- a/core/src/test/java/org/apache/servicecomb/core/invocation/endpoint/EndpointTest.java +++ b/core/src/test/java/org/apache/servicecomb/core/invocation/endpoint/EndpointTest.java @@ -26,7 +26,6 @@ import org.apache.servicecomb.core.Invocation; import org.apache.servicecomb.core.Transport; import org.apache.servicecomb.foundation.common.Holder; -import org.apache.servicecomb.swagger.SwaggerUtils; import org.apache.servicecomb.swagger.engine.SwaggerConsumer; import org.apache.servicecomb.swagger.engine.SwaggerConsumerOperation; import org.apache.servicecomb.swagger.engine.SwaggerEnvironment; @@ -46,22 +45,10 @@ void should_ignore_endpoint_when_generate_swagger() { SwaggerGenerator generator = SwaggerGenerator.create(TestSchema.class); OpenAPI swagger = generator.generate(); - assertThat(SwaggerUtils.swaggerToString(swagger)) - .isEqualTo("openapi: 3.0.1\n" - + "info:\n" - + " title: swagger definition for org.apache.servicecomb.core.invocation.endpoint.EndpointTest$TestSchema\n" - + " version: 1.0.0\n" - + "servers:\n" - + "- url: /TestSchema\n" - + "paths:\n" - + " /say:\n" - + " post:\n" - + " operationId: say\n" - + " responses:\n" - + " \"200\":\n" - + " description: response of 200\n" - + "components: {}\n" - + ""); + assertThat(swagger.getInfo().getTitle()).contains("EndpointTest$TestSchema"); + assertThat(swagger.getPaths()).containsKey("/say"); + assertThat(swagger.getPaths().get("/say").getPost().getOperationId()).isEqualTo("say"); + assertThat(swagger.getPaths().get("/say").getPost().getResponses()).containsKey("200"); } @Test diff --git a/core/src/test/java/org/apache/servicecomb/core/transport/TestAbstractTransport.java b/core/src/test/java/org/apache/servicecomb/core/transport/TestAbstractTransport.java index 934381fe455..65c44b12560 100644 --- a/core/src/test/java/org/apache/servicecomb/core/transport/TestAbstractTransport.java +++ b/core/src/test/java/org/apache/servicecomb/core/transport/TestAbstractTransport.java @@ -32,7 +32,7 @@ import org.mockito.Mockito; import org.springframework.core.env.Environment; -import io.vertx.core.file.impl.FileResolverImpl; +import io.vertx.core.impl.SysProps; public class TestAbstractTransport { Environment environment = Mockito.mock(Environment.class); @@ -56,7 +56,7 @@ public void setUp() { Mockito.when(environment.getProperty("servicecomb.my.publishPort", int.class, 0)).thenReturn(0); Mockito.when(environment.getProperty("servicecomb.transport.eventloop.size", int.class, -1)) .thenReturn(-1); - Mockito.when(environment.getProperty(FileResolverImpl.DISABLE_CP_RESOLVING_PROP_NAME, boolean.class, true)) + Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true)) .thenReturn(true); LegacyPropertyFactory.setEnvironment(environment); } diff --git a/coverage-reports/pom.xml b/coverage-reports/pom.xml index 7bb79b0ce8c..97f795fcbf5 100644 --- a/coverage-reports/pom.xml +++ b/coverage-reports/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default 4.0.0 diff --git a/demo/demo-consul/README.md b/demo/demo-consul/README.md new file mode 100644 index 00000000000..872a1d2e93a --- /dev/null +++ b/demo/demo-consul/README.md @@ -0,0 +1,5 @@ +# Notice + +This integration tests is designed for Consul registry and configuration. And extra test cases include: + +* Test cases related to SpringMVC annotations that demo-springmvc can not cover. diff --git a/demo/demo-consul/consumer/pom.xml b/demo/demo-consul/consumer/pom.xml new file mode 100644 index 00000000000..eccc75e41b1 --- /dev/null +++ b/demo/demo-consul/consumer/pom.xml @@ -0,0 +1,104 @@ + + + + 4.0.0 + + + org.apache.servicecomb.demo + demo-consul + 3.4.0-SNAPSHOT + + + consul-consumer + Java Chassis::Demo::Consul::CONSUMER + jar + + + + org.apache.servicecomb + java-chassis-spring-boot-starter-standalone + + + org.apache.servicecomb + registry-consul + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + docker + + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + + + + io.fabric8 + docker-maven-plugin + + + + + + diff --git a/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ClientWebsocketController.java b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ClientWebsocketController.java new file mode 100644 index 00000000000..f71738a9ed6 --- /dev/null +++ b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ClientWebsocketController.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import org.apache.servicecomb.core.CoreConst; +import org.apache.servicecomb.core.annotation.Transport; +import org.apache.servicecomb.provider.pojo.RpcReference; +import org.apache.servicecomb.provider.rest.common.RestSchema; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import io.vertx.core.http.ServerWebSocket; +import io.vertx.core.http.WebSocket; + +@RestSchema(schemaId = "ClientWebsocketController") +@RequestMapping(path = "/ws") +public class ClientWebsocketController { + interface ProviderService { + WebSocket websocket(); + } + + @RpcReference(schemaId = "WebsocketController", microserviceName = "provider") + private ProviderService providerService; + + @PostMapping("/websocket") + @Transport(name = CoreConst.WEBSOCKET) + public void websocket(ServerWebSocket serverWebsocket) { + WebSocket providerWebSocket = providerService.websocket(); + providerWebSocket.closeHandler(v -> serverWebsocket.close()); + providerWebSocket.textMessageHandler(m -> { + serverWebsocket.writeTextMessage(m); + }); + serverWebsocket.textMessageHandler(m -> { + providerWebSocket.writeTextMessage(m); + }); + } +} diff --git a/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsulConsumerApplication.java b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsulConsumerApplication.java new file mode 100644 index 00000000000..da243836198 --- /dev/null +++ b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsulConsumerApplication.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +@SpringBootApplication +public class ConsulConsumerApplication { + public static void main(String[] args) throws Exception { + try { + new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(ConsulConsumerApplication.class).run(args); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java new file mode 100644 index 00000000000..e66fb2cb3d0 --- /dev/null +++ b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import org.apache.servicecomb.provider.pojo.RpcReference; +import org.apache.servicecomb.provider.rest.common.RestSchema; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +@RestSchema(schemaId = "ConsumerController") +@RequestMapping(path = "/") +public class ConsumerController { + @RpcReference(schemaId = "ProviderController", microserviceName = "provider") + private ProviderService providerService; + + // consumer service which delegate the implementation to provider service. + @GetMapping("/sayHello") + public String sayHello(@RequestParam("name") String name) { + return providerService.sayHello(name); + } + + @GetMapping("/getConfig") + public String getConfig(@RequestParam("key") String key) { + return providerService.getConfig(key); + } + + @PostMapping(path = "/testContentType", consumes = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + public User testContentType(@RequestBody User user) { + return providerService.testContentType(user); + } +} diff --git a/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerHeaderParamWithListSchema.java b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerHeaderParamWithListSchema.java new file mode 100644 index 00000000000..f0e894d6745 --- /dev/null +++ b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerHeaderParamWithListSchema.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import java.util.List; + +import org.apache.servicecomb.demo.api.IHeaderParamWithListSchemaSpringMvc; +import org.apache.servicecomb.provider.pojo.RpcReference; +import org.apache.servicecomb.provider.rest.common.RestSchema; + +@RestSchema(schemaId = "ConsumerHeaderParamWithListSchema", schemaInterface = IHeaderParamWithListSchemaSpringMvc.class) +public class ConsumerHeaderParamWithListSchema implements IHeaderParamWithListSchemaSpringMvc { + @RpcReference(microserviceName = "provider", schemaId = "HeaderParamWithListSchema") + private IHeaderParamWithListSchemaSpringMvc provider; + + @Override + public String headerListDefault(List headerList) { + return provider.headerListDefault(headerList); + } + + @Override + public String headerListCSV(List headerList) { + return provider.headerListCSV(headerList); + } + + @Override + public String headerListMULTI(List headerList) { + return provider.headerListMULTI(headerList); + } + + @Override + public String headerListSSV(List headerList) { + return provider.headerListSSV(headerList); + } + + @Override + public String headerListPIPES(List headerList) { + return provider.headerListPIPES(headerList); + } +} diff --git a/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerReactiveStreamController.java b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerReactiveStreamController.java new file mode 100644 index 00000000000..aa169801cf7 --- /dev/null +++ b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerReactiveStreamController.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.servicecomb.samples; + + +import org.apache.servicecomb.core.CoreConst; +import org.apache.servicecomb.core.annotation.Transport; +import org.apache.servicecomb.provider.pojo.RpcReference; +import org.apache.servicecomb.provider.rest.common.RestSchema; +import org.reactivestreams.Publisher; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@RestSchema(schemaId = "ReactiveStreamController") +@RequestMapping(path = "/") +public class ConsumerReactiveStreamController { + interface ProviderReactiveStreamController { + Publisher sseString(); + + Publisher sseModel(); + } + + @RpcReference(microserviceName = "provider", schemaId = "ReactiveStreamController") + ProviderReactiveStreamController controller; + + public static class Model { + private String name; + + private int age; + + public Model() { + + } + + public Model(String name, int age) { + this.name = name; + this.age = age; + } + + public int getAge() { + return age; + } + + public Model setAge(int age) { + this.age = age; + return this; + } + + public String getName() { + return name; + } + + public Model setName(String name) { + this.name = name; + return this; + } + } + + @GetMapping("/sseString") + @Transport(name = CoreConst.RESTFUL) + public Publisher sseString() { + return controller.sseString(); + } + + @GetMapping("/sseModel") + @Transport(name = CoreConst.RESTFUL) + public Publisher sseModel() { + return controller.sseModel(); + } +} diff --git a/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java new file mode 100644 index 00000000000..2899546c752 --- /dev/null +++ b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +public interface ProviderService { + String sayHello(String name); + + String getConfig(String key); + + User testContentType(User user); +} diff --git a/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/User.java b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/User.java new file mode 100644 index 00000000000..ff421930ef2 --- /dev/null +++ b/demo/demo-consul/consumer/src/main/java/org/apache/servicecomb/samples/User.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.servicecomb.samples; + + +public class User { + + private Long id; + + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/demo/demo-consul/consumer/src/main/resources/application.yml b/demo/demo-consul/consumer/src/main/resources/application.yml new file mode 100644 index 00000000000..ef0d45c1dcb --- /dev/null +++ b/demo/demo-consul/consumer/src/main/resources/application.yml @@ -0,0 +1,40 @@ +# +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +servicecomb: + service: + application: demo-consul + version: 0.0.1 + name: consumer + properties: + group: green + + registry: + consul: + enabled: true + host: 127.0.0.1 + scheme: http + discovery: + enabled: true + acl-token: '' + watch-seconds: 8 + + rest: + address: 0.0.0.0:9092?websocketEnabled=true + server: + websocket-prefix: /ws diff --git a/demo/demo-consul/consumer/src/main/resources/log4j2.xml b/demo/demo-consul/consumer/src/main/resources/log4j2.xml new file mode 100644 index 00000000000..c51f7ad5036 --- /dev/null +++ b/demo/demo-consul/consumer/src/main/resources/log4j2.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + diff --git a/demo/demo-consul/gateway/pom.xml b/demo/demo-consul/gateway/pom.xml new file mode 100644 index 00000000000..1dad3860e7f --- /dev/null +++ b/demo/demo-consul/gateway/pom.xml @@ -0,0 +1,107 @@ + + + + 4.0.0 + + + org.apache.servicecomb.demo + demo-consul + 3.4.0-SNAPSHOT + + + consul-gateway + Java Chassis::Demo::Consul::GATEWAY + jar + + + + org.apache.servicecomb + java-chassis-spring-boot-starter-standalone + + + org.apache.servicecomb + edge-core + + + org.apache.servicecomb + registry-consul + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + docker + + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + + + + io.fabric8 + docker-maven-plugin + + + + + + diff --git a/demo/demo-consul/gateway/src/main/java/org/apache/servicecomb/samples/GatewayApplication.java b/demo/demo-consul/gateway/src/main/java/org/apache/servicecomb/samples/GatewayApplication.java new file mode 100644 index 00000000000..7d58caafd9d --- /dev/null +++ b/demo/demo-consul/gateway/src/main/java/org/apache/servicecomb/samples/GatewayApplication.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +@SpringBootApplication +public class GatewayApplication { + public static void main(String[] args) throws Exception { + try { + new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(GatewayApplication.class).run(args); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/demo/demo-consul/gateway/src/main/resources/application.yml b/demo/demo-consul/gateway/src/main/resources/application.yml new file mode 100644 index 00000000000..9855a87a1de --- /dev/null +++ b/demo/demo-consul/gateway/src/main/resources/application.yml @@ -0,0 +1,60 @@ +# +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +servicecomb: + service: + application: demo-consul + version: 0.0.1 + name: gateway + + registry: + consul: + enabled: true + host: 127.0.0.1 + scheme: http + discovery: + enabled: true + acl-token: '' + watch-seconds: 8 + + rest: + address: 0.0.0.0:9090?websocketEnabled=true + server: + websocket-prefix: /ws + + http: + dispatcher: + edge: + default: + enabled: false + url: + enabled: true + pattern: /(.*) + mappings: + consumer: + prefixSegmentCount: 0 + path: "/.*" + microserviceName: consumer + versionRule: 0.0.0+ + websocket: + mappings: + consumer: + prefixSegmentCount: 0 + path: "/ws/.*" + microserviceName: consumer + versionRule: 0.0.0+ diff --git a/demo/demo-consul/gateway/src/main/resources/log4j2.xml b/demo/demo-consul/gateway/src/main/resources/log4j2.xml new file mode 100644 index 00000000000..c51f7ad5036 --- /dev/null +++ b/demo/demo-consul/gateway/src/main/resources/log4j2.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + diff --git a/demo/demo-consul/pom.xml b/demo/demo-consul/pom.xml new file mode 100644 index 00000000000..aaa8f3b91ce --- /dev/null +++ b/demo/demo-consul/pom.xml @@ -0,0 +1,62 @@ + + + + + 4.0.0 + + org.apache.servicecomb.demo + demo-parent + 3.4.0-SNAPSHOT + + + demo-consul + Java Chassis::Demo::Consul + pom + + + + org.apache.servicecomb.demo + demo-schema + + + org.apache.servicecomb + solution-basic + + + org.apache.logging.log4j + log4j-slf4j-impl + + + org.apache.logging.log4j + log4j-core + + + org.apache.logging.log4j + log4j-api + + + + + provider + consumer + gateway + test-client + + diff --git a/demo/demo-consul/provider/pom.xml b/demo/demo-consul/provider/pom.xml new file mode 100644 index 00000000000..0986f9f4342 --- /dev/null +++ b/demo/demo-consul/provider/pom.xml @@ -0,0 +1,114 @@ + + + + + 4.0.0 + + + org.apache.servicecomb.demo + demo-consul + 3.4.0-SNAPSHOT + + + consul-provider + Java Chassis::Demo::Consul::PROVIDER + jar + + + + org.apache.servicecomb + java-chassis-spring-boot-starter-standalone + + + org.apache.servicecomb + registry-consul + + + org.apache.servicecomb + config-consul + + + + io.reactivex.rxjava3 + rxjava + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + docker + + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + + + + io.fabric8 + docker-maven-plugin + + + + + + diff --git a/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/ConsulProviderApplication.java b/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/ConsulProviderApplication.java new file mode 100644 index 00000000000..b84da167943 --- /dev/null +++ b/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/ConsulProviderApplication.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +@SpringBootApplication +public class ConsulProviderApplication { + public static void main(String[] args) throws Exception { + try { + new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(ConsulProviderApplication.class).run(args); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchema.java b/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchema.java new file mode 100644 index 00000000000..8a773f91c72 --- /dev/null +++ b/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchema.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import java.util.List; + +import org.apache.servicecomb.demo.api.IHeaderParamWithListSchemaSpringMvc; +import org.apache.servicecomb.provider.rest.common.RestSchema; + +@RestSchema(schemaId = "HeaderParamWithListSchema", schemaInterface = IHeaderParamWithListSchemaSpringMvc.class) +public class HeaderParamWithListSchema implements IHeaderParamWithListSchemaSpringMvc { + @Override + public String headerListDefault(List headerList) { + return headerList == null ? "null" : headerList.size() + ":" + headerList; + } + + @Override + public String headerListCSV(List headerList) { + return headerList == null ? "null" : headerList.size() + ":" + headerList; + } + + @Override + public String headerListMULTI(List headerList) { + return headerList == null ? "null" : headerList.size() + ":" + headerList; + } + + @Override + public String headerListSSV(List headerList) { + return headerList == null ? "null" : headerList.size() + ":" + headerList; + } + + @Override + public String headerListPIPES(List headerList) { + return headerList == null ? "null" : headerList.size() + ":" + headerList; + } +} diff --git a/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java b/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java new file mode 100644 index 00000000000..677c20ed106 --- /dev/null +++ b/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import org.apache.servicecomb.provider.rest.common.RestSchema; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +@RestSchema(schemaId = "ProviderController") +@RequestMapping(path = "/") +public class ProviderController implements InitializingBean { + private Environment environment; + + @Autowired + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + // a very simple service to echo the request parameter + @GetMapping("/sayHello") + public String sayHello(@RequestParam("name") String name) { +// return "Hello " + environment.getProperty("servicecomb.rest.address"); + return "Hello " + name; + } + + @GetMapping("/getConfig") + public String getConfig(@RequestParam("key") String key) { + return environment.getProperty(key); + } + + @PostMapping(path = "/testContentType", consumes = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + public User testContentType(@RequestBody User user) { + return user; + } + + @Override + public void afterPropertiesSet() throws Exception { + } +} diff --git a/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/ReactiveStreamController.java b/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/ReactiveStreamController.java new file mode 100644 index 00000000000..8108d15fd46 --- /dev/null +++ b/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/ReactiveStreamController.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.servicecomb.samples; + + +import java.util.concurrent.TimeUnit; + +import org.apache.servicecomb.core.CoreConst; +import org.apache.servicecomb.core.annotation.Transport; +import org.apache.servicecomb.provider.rest.common.RestSchema; +import org.reactivestreams.Publisher; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import io.reactivex.rxjava3.core.Flowable; + +@RestSchema(schemaId = "ReactiveStreamController") +@RequestMapping(path = "/") +@Transport(name = CoreConst.RESTFUL) +public class ReactiveStreamController { + public static class Model { + private String name; + + private int age; + + public Model() { + + } + + public Model(String name, int age) { + this.name = name; + this.age = age; + } + + public int getAge() { + return age; + } + + public Model setAge(int age) { + this.age = age; + return this; + } + + public String getName() { + return name; + } + + public Model setName(String name) { + this.name = name; + return this; + } + } + + @GetMapping("/sseString") + public Publisher sseString() { + return Flowable.fromArray("a", "b", "c"); + } + + @GetMapping("/sseModel") + public Publisher sseModel() { + return Flowable.intervalRange(0, 5, 0, 1, TimeUnit.SECONDS) + .map(item -> new Model("jack", item.intValue())); + } +} diff --git a/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/User.java b/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/User.java new file mode 100644 index 00000000000..ca12402d672 --- /dev/null +++ b/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/User.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.servicecomb.samples; + +public class User { + + private Long id; + + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java b/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java new file mode 100644 index 00000000000..6381ef1d54c --- /dev/null +++ b/demo/demo-consul/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.servicecomb.core.CoreConst; +import org.apache.servicecomb.core.annotation.Transport; +import org.apache.servicecomb.provider.rest.common.RestSchema; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import io.vertx.core.http.ServerWebSocket; + +@RestSchema(schemaId = "WebsocketController") +@RequestMapping(path = "/ws") +public class WebsocketController { + @PostMapping("/websocket") + @Transport(name = CoreConst.WEBSOCKET) + public void websocket(ServerWebSocket serverWebsocket) { + AtomicInteger receiveCount = new AtomicInteger(0); + CountDownLatch startSend = new CountDownLatch(1); + serverWebsocket.textMessageHandler(s -> { + if ("start".equals(s)) { + startSend.countDown(); + serverWebsocket.writeTextMessage("started"); + return; + } + receiveCount.getAndIncrement(); + }); + serverWebsocket.closeHandler((v) -> System.out.println("closed")); + + new Thread(() -> { + try { + startSend.await(30, TimeUnit.SECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + serverWebsocket.writeTextMessage("hello"); + + for (int i = 0; i < 5; i++) { + serverWebsocket.writeTextMessage("hello " + i); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + serverWebsocket.writeTextMessage("total " + receiveCount.get()); + serverWebsocket.close(); + }).start(); + } +} diff --git a/demo/demo-consul/provider/src/main/resources/application.yml b/demo/demo-consul/provider/src/main/resources/application.yml new file mode 100644 index 00000000000..31bbfa5d4c7 --- /dev/null +++ b/demo/demo-consul/provider/src/main/resources/application.yml @@ -0,0 +1,67 @@ +# +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +# spring boot configurations +servicecomb: + service: + application: demo-consul + version: 0.0.1 + name: provider + properties: + group: green + + registry: + consul: + enabled: true + host: 127.0.0.1 + scheme: http + discovery: + enabled: true + acl-token: '' + watch-seconds: 8 + + config: + consul: + enabled: true + host: 127.0.0.1 + scheme: http + acl-token: '' + watch-seconds: 8 + + rest: + address: 0.0.0.0:9094?websocketEnabled=true + server: + websocket-prefix: /ws + + cors: + enabled: true + origin: "*" + allowCredentials: false + allowedMethod: "*" + maxAge: 3600 + + +key1: 1 +key2: 3 +key3: 5 + +test1: env +test2: applition +test3: service +test4: version +test5: tag diff --git a/demo/demo-consul/provider/src/main/resources/log4j2.xml b/demo/demo-consul/provider/src/main/resources/log4j2.xml new file mode 100644 index 00000000000..c51f7ad5036 --- /dev/null +++ b/demo/demo-consul/provider/src/main/resources/log4j2.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + diff --git a/demo/demo-consul/test-client/pom.xml b/demo/demo-consul/test-client/pom.xml new file mode 100644 index 00000000000..791ac474886 --- /dev/null +++ b/demo/demo-consul/test-client/pom.xml @@ -0,0 +1,220 @@ + + + + + 4.0.0 + + + org.apache.servicecomb.demo + demo-consul + 3.4.0-SNAPSHOT + + + consul-test-client + Java Chassis::Demo::Consul::TEST-CLIENT + jar + + + + + + + org.apache.servicecomb + java-chassis-spring-boot-starter-standalone + + + org.apache.servicecomb.demo + demo-schema + + + org.apache.servicecomb + registry-local + + + org.kiwiproject + consul-client + + + com.google.code.gson + gson + + + + + + docker + + + + + io.fabric8 + docker-maven-plugin + + + + hashicorp/consul:1.21 + consul + + alias + + consulServer + + + 8500 + + + + + + 8500:8500 + + + yes + + + + + consul-provider:${project.version} + consul-provider + + alias + + + -Dservicecomb.registry.consul.enabled=true + -Dservicecomb.registry.consul.scheme=http + -Dservicecomb.registry.consul.host=consul + -Dservicecomb.registry.consul.port=8500 + -Dservicecomb.config.consul.enabled=true + -Dservicecomb.config.consul.scheme=http + -Dservicecomb.config.consul.host=consul + -Dservicecomb.config.consul.port=8500 + + /maven/maven/consul-provider-${project.version}.jar + + + consul:consul + + + ServiceComb is ready + + + 9094 + + + + + + 9094:9094 + + + + + consul-consumer:${project.version} + consul-consumer + + alias + + + -Dservicecomb.registry.consul.enabled=true + -Dservicecomb.registry.consul.scheme=http + -Dservicecomb.registry.consul.host=consul + -Dservicecomb.registry.consul.port=8500 + + /maven/maven/consul-consumer-${project.version}.jar + + + consul:consul + + + ServiceComb is ready + + + 9092 + + + + + + 9092:9092 + + + + + consul-gateway:${project.version} + consul-gateway + + alias + + + -Dservicecomb.registry.consul.enabled=true + -Dservicecomb.registry.consul.scheme=http + -Dservicecomb.registry.consul.host=consul + -Dservicecomb.registry.consul.port=8500 + + /maven/maven/consul-gateway-${project.version}.jar + + + consul:consul + + + ServiceComb is ready + + + 9090 + + + + + + 9090:9090 + + + + + + + + start + pre-integration-test + + start + + + + stop + post-integration-test + + stop + + + + + + + + + + io.fabric8 + docker-maven-plugin + + + + + + diff --git a/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/Config.java b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/Config.java new file mode 100644 index 00000000000..2e9105cdd4a --- /dev/null +++ b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/Config.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +public interface Config { + String GATEWAY_URL = "http://localhost:9090"; +} diff --git a/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ConsulConfigIT.java b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ConsulConfigIT.java new file mode 100644 index 00000000000..1a7be4b874d --- /dev/null +++ b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ConsulConfigIT.java @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import com.google.common.net.HostAndPort; +import org.apache.commons.lang3.StringUtils; +import org.apache.servicecomb.demo.CategorizedTestCase; +import org.apache.servicecomb.demo.TestMgr; +import org.apache.servicecomb.foundation.common.utils.ConditionWaiter.SleepUtil; +import org.kiwiproject.consul.Consul; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestOperations; +import org.springframework.web.client.RestTemplate; + +import java.util.concurrent.TimeUnit; + +@Component +public class ConsulConfigIT implements CategorizedTestCase { + RestOperations template = new RestTemplate(); + + private static final Logger LOGGER = LoggerFactory.getLogger(ConsulConfigIT.class); + + @Override + public void testRestTransport() throws Exception { + + testEnvironment(); + testApplication(); + testService(); + testVersion(); + testTag(); + testOverride(); + } + + private void testOverride() { + + putValue("/servicecomb/config/environment/production/application2.properties", + "testValue=t1"); + putValue("/servicecomb/config/application/production/demo-consul/application2.properties", + "testValue=t2"); + testGetConfig("testValue", "t2"); + putValue("/servicecomb/config/service/production/demo-consul/provider/application2.properties", + "testValue=t3"); + testGetConfig("testValue", "t3"); + putValue("/servicecomb/config/version/production/demo-consul/provider/0.0.1/application2.properties", + "testValue=t4"); + testGetConfig("testValue", "t4"); + putValue("/servicecomb/config/tag/production/demo-consul/provider/0.0.1/tag1/application2.properties", + "testValue=t5"); + testGetConfig("testValue", "t5"); + } + + private void testEnvironment() { + + putValue("/servicecomb/config/environment/production/application.properties", + "test1=env"); + putValue("/servicecomb/config/environment/production/application.properties", + "test1=env1"); + + testGetConfig("test1", "env1"); + } + + + private void testApplication() { + + putValue("/servicecomb/config/application/production/demo-consul/application.properties", + "test2=applition"); + putValue("/servicecomb/config/application/production/demo-consul/application.properties", + "test2=applition2"); + testGetConfig("test2", "applition2"); + } + + private void testService() { + + putValue("/servicecomb/config/service/production/demo-consul/provider/application.properties", + "test3=service"); + putValue("/servicecomb/config/service/production/demo-consul/provider/application.properties", + "test3=service3"); + testGetConfig("test3", "service3"); + } + + private void testVersion() { + + putValue("/servicecomb/config/version/production/demo-consul/provider/0.0.1/application.properties", + "test3=version"); + putValue("/servicecomb/config/version/production/demo-consul/provider/0.0.1/application.properties", + "test4=version4"); + testGetConfig("test4", "version4"); + } + + private void testTag() { + + putValue("/servicecomb/config/tag/production/demo-consul/provider/0.0.1/tag1/application.properties", + "test5=tag"); + putValue("/servicecomb/config/tag/production/demo-consul/provider/0.0.1/tag1/application.properties", + "test5=tag5"); + testGetConfig("test5", "tag5"); + } + + public void putValue(String key, String value) { + try { + Consul.Builder builder = Consul.builder().withHostAndPort(HostAndPort.fromParts("127.0.0.1", 8500)); + Consul consulClient = builder.build(); + consulClient.keyValueClient().putValue(key, value); + LOGGER.info("Value set successfully:{}", value); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void testGetConfig(String key, String expectValue) { + + String result = template + .getForObject(Config.GATEWAY_URL + "/getConfig?key=" + key, String.class); + + for (int i = 0; i < 4; i++) { + if (StringUtils.equals(expectValue, result)) { + TestMgr.check(expectValue, result); + break; + } + SleepUtil.sleep(500, TimeUnit.MILLISECONDS); + } + } +} diff --git a/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchemaIT.java b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchemaIT.java new file mode 100644 index 00000000000..1b129acc2c6 --- /dev/null +++ b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/HeaderParamWithListSchemaIT.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import org.apache.servicecomb.demo.CategorizedTestCase; +import org.apache.servicecomb.demo.TestMgr; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.stereotype.Component; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestOperations; +import org.springframework.web.client.RestTemplate; + +@Component +public class HeaderParamWithListSchemaIT implements CategorizedTestCase { + RestOperations template = new RestTemplate(); + + @Override + public void testRestTransport() throws Exception { + testHeaderListDefault(); + testHeaderListMulti(); + testHeaderListCSV(); + testHeaderListSSV(); + testHeaderListPipes(); + } + + // default to multi + private void testHeaderListDefault() { + MultiValueMap headers = new HttpHeaders(); + headers.add("headerList", "a"); + headers.add("headerList", "b"); + headers.add("headerList", "c"); + HttpEntity entity = new HttpEntity<>(headers); + String result = template + .exchange(Config.GATEWAY_URL + "/headerList/headerListDefault", HttpMethod.GET, entity, String.class).getBody(); + TestMgr.check("3:[a, b, c]", result); + } + + private void testHeaderListPipes() { + MultiValueMap headers = new HttpHeaders(); + headers.add("headerList", "a|b|c"); + HttpEntity entity = new HttpEntity<>(headers); + String result = template + .exchange(Config.GATEWAY_URL + "/headerList/headerListPIPES", HttpMethod.GET, entity, String.class).getBody(); + TestMgr.check("3:[a, b, c]", result); + } + + private void testHeaderListSSV() { + MultiValueMap headers = new HttpHeaders(); + headers.add("headerList", "a b c"); + HttpEntity entity = new HttpEntity<>(headers); + String result = template + .exchange(Config.GATEWAY_URL + "/headerList/headerListSSV", HttpMethod.GET, entity, String.class).getBody(); + TestMgr.check("3:[a, b, c]", result); + } + + private void testHeaderListCSV() { + MultiValueMap headers = new HttpHeaders(); + headers.add("headerList", "a,b,c"); + HttpEntity entity = new HttpEntity<>(headers); + String result = template + .exchange(Config.GATEWAY_URL + "/headerList/headerListCSV", HttpMethod.GET, entity, String.class).getBody(); + TestMgr.check("3:[a, b, c]", result); + + headers.add("headerList", "a, b, c"); + entity = new HttpEntity<>(headers); + result = template + .exchange(Config.GATEWAY_URL + "/headerList/headerListCSV", HttpMethod.GET, entity, String.class).getBody(); + TestMgr.check("3:[a, b, c]", result); + } + + private void testHeaderListMulti() { + MultiValueMap headers = new HttpHeaders(); + headers.add("headerList", "a"); + headers.add("headerList", "b"); + headers.add("headerList", "c"); + HttpEntity entity = new HttpEntity<>(headers); + String result = template + .exchange(Config.GATEWAY_URL + "/headerList/headerListMULTI", HttpMethod.GET, entity, String.class).getBody(); + TestMgr.check("3:[a, b, c]", result); + } +} diff --git a/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java new file mode 100644 index 00000000000..97e883fb45f --- /dev/null +++ b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import org.apache.servicecomb.demo.CategorizedTestCase; +import org.apache.servicecomb.demo.TestMgr; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestOperations; +import org.springframework.web.client.RestTemplate; + +@Component +public class HelloWorldIT implements CategorizedTestCase { + RestOperations template = new RestTemplate(); + + @Override + public void testRestTransport() throws Exception { + testHelloWorld(); + testGetConfig(); + } + + private void testGetConfig() { + String result = template + .getForObject(Config.GATEWAY_URL + "/getConfig?key=key1", String.class); + TestMgr.check("1", result); + result = template + .getForObject(Config.GATEWAY_URL + "/getConfig?key=key2", String.class); + TestMgr.check("3", result); + result = template + .getForObject(Config.GATEWAY_URL + "/getConfig?key=key3", String.class); + TestMgr.check("5", result); + } + + private void testHelloWorld() { + String result = template + .getForObject(Config.GATEWAY_URL + "/sayHello?name=World", String.class); + TestMgr.check("Hello World", result); + + // test trace id added + MultiValueMap headers = new HttpHeaders(); + headers.add("X-B3-TraceId", "81de2eb7691c2bbb"); + HttpEntity entity = new HttpEntity(headers); + ResponseEntity response = + template.exchange(Config.GATEWAY_URL + "/sayHello?name=World", HttpMethod.GET, entity, String.class); + TestMgr.check(1, response.getHeaders().get("X-B3-TraceId").size()); + TestMgr.check("81de2eb7691c2bbb", response.getHeaders().getFirst("X-B3-TraceId")); + TestMgr.check("Hello World", response.getBody()); + } +} diff --git a/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ProviderIT.java b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ProviderIT.java new file mode 100644 index 00000000000..2bdd0ca42ca --- /dev/null +++ b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ProviderIT.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.servicecomb.samples; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import org.apache.servicecomb.demo.CategorizedTestCase; +import org.apache.servicecomb.demo.TestMgr; +import org.apache.servicecomb.foundation.common.utils.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestOperations; +import org.springframework.web.client.RestTemplate; + +@Component +public class ProviderIT implements CategorizedTestCase { + + RestOperations template = new RestTemplate(); + + private static final Logger LOGGER = LoggerFactory.getLogger(ProviderIT.class); + + @Override + public void testRestTransport() throws Exception { + + User user = getUser("Application/json"); + TestMgr.check(1L, user.getId()); + TestMgr.check("czd", user.getName()); + + User user2 = getUser("application/json"); + TestMgr.check(1L, user2.getId()); + TestMgr.check("czd", user2.getName()); + + User user3 = getUser("APPLICATION/JSON"); + TestMgr.check(1L, user3.getId()); + TestMgr.check("czd", user3.getName()); + } + + private User getUser(String contentType) throws IOException { + HttpHeaders headers = new HttpHeaders(); + headers.set("Content-Type", contentType); + + String requestBody = """ + { + "id": 1, + "name": "czd" + } + """; + + HttpEntity entity = new HttpEntity<>(requestBody, headers); + + String url = Config.GATEWAY_URL + "/testContentType"; + ResponseEntity response = template.exchange( + url, HttpMethod.POST, entity, String.class); + + User user = JsonUtils.readValue(response.getBody().getBytes(StandardCharsets.UTF_8), User.class); + return user; + } +} diff --git a/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ReactiveStreamIT.java b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ReactiveStreamIT.java new file mode 100644 index 00000000000..488a6cf712a --- /dev/null +++ b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ReactiveStreamIT.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.apache.servicecomb.demo.CategorizedTestCase; +import org.apache.servicecomb.demo.TestMgr; +import org.apache.servicecomb.samples.ThirdSvcConfiguration.ReactiveStreamClient; +import org.apache.servicecomb.samples.ThirdSvcConfiguration.ReactiveStreamClient.Model; +import org.reactivestreams.Publisher; +import org.reactivestreams.Subscriber; +import org.reactivestreams.Subscription; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +@Component +public class ReactiveStreamIT implements CategorizedTestCase { + @Autowired + @Qualifier("reactiveStreamProvider") + ReactiveStreamClient reactiveStreamProvider; + + @Autowired + @Qualifier("reactiveStreamGateway") + ReactiveStreamClient reactiveStreamGateway; + + @Override + public void testRestTransport() throws Exception { + testSseString(reactiveStreamProvider); + testSseModel(reactiveStreamProvider); + testSseString(reactiveStreamGateway); + testSseModel(reactiveStreamGateway); + } + + private void testSseModel(ReactiveStreamClient client) throws Exception { + Publisher result = client.sseModel(); + StringBuilder buffer = new StringBuilder(); + CountDownLatch countDownLatch = new CountDownLatch(1); + result.subscribe(new Subscriber<>() { + Subscription subscription; + + @Override + public void onSubscribe(Subscription s) { + subscription = s; + subscription.request(1); + } + + @Override + public void onNext(Model s) { + buffer.append(s.getName()).append(s.getAge()); + subscription.request(1); + } + + @Override + public void onError(Throwable t) { + subscription.cancel(); + countDownLatch.countDown(); + } + + @Override + public void onComplete() { + countDownLatch.countDown(); + } + }); + countDownLatch.await(10, TimeUnit.SECONDS); + TestMgr.check("jack0jack1jack2jack3jack4", buffer.toString()); + } + + private void testSseString(ReactiveStreamClient client) throws Exception { + Publisher result = client.sseString(); + StringBuilder buffer = new StringBuilder(); + CountDownLatch countDownLatch = new CountDownLatch(1); + result.subscribe(new Subscriber<>() { + Subscription subscription; + + @Override + public void onSubscribe(Subscription s) { + subscription = s; + subscription.request(1); + } + + @Override + public void onNext(String s) { + buffer.append(s); + subscription.request(1); + } + + @Override + public void onError(Throwable t) { + subscription.cancel(); + countDownLatch.countDown(); + } + + @Override + public void onComplete() { + countDownLatch.countDown(); + } + }); + countDownLatch.await(10, TimeUnit.SECONDS); + TestMgr.check("abc", buffer.toString()); + } +} diff --git a/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/TestClientApplication.java b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/TestClientApplication.java new file mode 100644 index 00000000000..26a2a491bbe --- /dev/null +++ b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/TestClientApplication.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import org.apache.servicecomb.demo.CategorizedTestCaseRunner; +import org.apache.servicecomb.demo.TestMgr; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +@SpringBootApplication +public class TestClientApplication { + private static final Logger LOGGER = LoggerFactory.getLogger(TestClientApplication.class); + + public static void main(String[] args) throws Exception { + try { + new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(TestClientApplication.class).run(args); + + run(); + } catch (Exception e) { + TestMgr.failed("test case run failed", e); + LOGGER.error("-------------- test failed -------------"); + LOGGER.error("", e); + LOGGER.error("-------------- test failed -------------"); + } + TestMgr.summary(); + } + + public static void run() throws Exception { + CategorizedTestCaseRunner.runCategorizedTestCase("consumer"); + } +} diff --git a/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ThirdSvcConfiguration.java b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ThirdSvcConfiguration.java new file mode 100644 index 00000000000..abe96a4f10b --- /dev/null +++ b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/ThirdSvcConfiguration.java @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import java.util.List; + +import org.apache.servicecomb.core.CoreConst; +import org.apache.servicecomb.core.annotation.Transport; +import org.apache.servicecomb.localregistry.RegistryBean; +import org.apache.servicecomb.localregistry.RegistryBean.Instance; +import org.apache.servicecomb.localregistry.RegistryBean.Instances; +import org.apache.servicecomb.provider.pojo.Invoker; +import org.reactivestreams.Publisher; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import io.vertx.core.http.WebSocket; + +@Configuration +public class ThirdSvcConfiguration { + @RequestMapping(path = "/ws") + public interface WebsocketClient { + @PostMapping("/websocket") + @Transport(name = CoreConst.WEBSOCKET) + WebSocket websocket(); + } + + @RequestMapping(path = "/") + public interface ReactiveStreamClient { + class Model { + private String name; + + private int age; + + public Model() { + + } + + public Model(String name, int age) { + this.name = name; + this.age = age; + } + + public int getAge() { + return age; + } + + public Model setAge(int age) { + this.age = age; + return this; + } + + public String getName() { + return name; + } + + public Model setName(String name) { + this.name = name; + return this; + } + } + + @GetMapping("/sseString") + Publisher sseString(); + + @GetMapping("/sseModel") + Publisher sseModel(); + } + + @Bean + public RegistryBean providerServiceBean() { + return new RegistryBean() + .addSchemaInterface("ReactiveStreamController", ReactiveStreamClient.class) + .setAppId("demo-consul") + .setServiceName("provider") + .setVersion("0.0.1") + .setInstances(new Instances().setInstances(List.of( + new Instance().setEndpoints(List.of("rest://localhost:9094"))))); + } + + @Bean + public RegistryBean gatewayServiceBean() { + return new RegistryBean() + .addSchemaInterface("ReactiveStreamController", ReactiveStreamClient.class) + .addSchemaInterface("WebsocketController", WebsocketClient.class) + .setAppId("demo-consul") + .setServiceName("gateway") + .setVersion("0.0.1") + .setInstances(new Instances().setInstances(List.of( + new Instance().setEndpoints(List.of("rest://localhost:9090?websocketEnabled=true"))))); + } + + @Bean("reactiveStreamProvider") + public ReactiveStreamClient reactiveStreamProvider() { + return Invoker.createProxy("provider", "ReactiveStreamController", ReactiveStreamClient.class); + } + + @Bean("reactiveStreamGateway") + public ReactiveStreamClient reactiveStreamGateway() { + return Invoker.createProxy("gateway", "ReactiveStreamController", ReactiveStreamClient.class); + } + + @Bean + public WebsocketClient gatewayWebsocketClient() { + return Invoker.createProxy("gateway", "WebsocketController", WebsocketClient.class); + } +} diff --git a/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/User.java b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/User.java new file mode 100644 index 00000000000..ff421930ef2 --- /dev/null +++ b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/User.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.servicecomb.samples; + + +public class User { + + private Long id; + + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/WebsocketIT.java b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/WebsocketIT.java new file mode 100644 index 00000000000..c36f2d16d28 --- /dev/null +++ b/demo/demo-consul/test-client/src/main/java/org/apache/servicecomb/samples/WebsocketIT.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.servicecomb.demo.CategorizedTestCase; +import org.apache.servicecomb.demo.TestMgr; +import org.apache.servicecomb.samples.ThirdSvcConfiguration.WebsocketClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import io.vertx.core.http.WebSocket; + +@Component +public class WebsocketIT implements CategorizedTestCase { + @Autowired + private WebsocketClient websocketClient; + + @Override + public void testRestTransport() throws Exception { + StringBuffer sb = new StringBuffer(); + AtomicBoolean closed = new AtomicBoolean(false); + CountDownLatch latchStarted = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); + + WebSocket webSocket = websocketClient.websocket(); + webSocket.textMessageHandler(s -> { + if ("started".equals(s)) { + latchStarted.countDown(); + return; + } + sb.append(s); + sb.append(" "); + webSocket.writeTextMessage(s); + }); + webSocket.closeHandler(v -> { + closed.set(true); + latch.countDown(); + }); + + webSocket.writeTextMessage("start"); + int i = 0; + for (; i < 10; i++) { + if (!latchStarted.await(3, TimeUnit.SECONDS)) { + webSocket.writeTextMessage("start"); + continue; + } + break; + } + TestMgr.check(i < 10, true); + latch.await(30, TimeUnit.SECONDS); + TestMgr.check(sb.toString(), "hello hello 0 hello 1 hello 2 hello 3 hello 4 total 6 "); + TestMgr.check(closed.get(), true); + } +} diff --git a/demo/demo-consul/test-client/src/main/resources/application.yml b/demo/demo-consul/test-client/src/main/resources/application.yml new file mode 100644 index 00000000000..718fbd9cc84 --- /dev/null +++ b/demo/demo-consul/test-client/src/main/resources/application.yml @@ -0,0 +1,40 @@ +# +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +servicecomb: + service: + application: demo-consul + name: test-client + version: 0.0.1 + + rest: + address: 0.0.0.0:9097 # should be same with server.port to use web container + + config: + consul: + enabled: true + host: 127.0.0.1 + scheme: http + acl-token: '' + instance-tag: tag1 + +test1: env +test2: applition +test3: service +test4: version +test5: tag diff --git a/demo/demo-consul/test-client/src/main/resources/log4j2.xml b/demo/demo-consul/test-client/src/main/resources/log4j2.xml new file mode 100644 index 00000000000..c51f7ad5036 --- /dev/null +++ b/demo/demo-consul/test-client/src/main/resources/log4j2.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + diff --git a/demo/demo-consul/test-client/src/test/java/org/apache/servicecomb/samples/ConsulIT.java b/demo/demo-consul/test-client/src/test/java/org/apache/servicecomb/samples/ConsulIT.java new file mode 100644 index 00000000000..62862743e27 --- /dev/null +++ b/demo/demo-consul/test-client/src/test/java/org/apache/servicecomb/samples/ConsulIT.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.samples; + +import org.apache.servicecomb.demo.TestMgr; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = TestClientApplication.class) +public class ConsulIT { + private static final Logger LOGGER = LoggerFactory.getLogger(ConsulIT.class); + + @BeforeEach + public void setUp() { + TestMgr.errors().clear(); + } + + @Test + public void clientGetsNoError() { + try { + TestClientApplication.run(); + } catch (Exception e) { + TestMgr.failed("test case run failed", e); + LOGGER.error("-------------- test failed -------------"); + LOGGER.error("", e); + LOGGER.error("-------------- test failed -------------"); + } + TestMgr.summary(); + Assertions.assertTrue(TestMgr.errors().isEmpty()); + } +} diff --git a/demo/demo-crossapp/crossapp-client/pom.xml b/demo/demo-crossapp/crossapp-client/pom.xml index c67cb17551e..fa2e051cd0f 100644 --- a/demo/demo-crossapp/crossapp-client/pom.xml +++ b/demo/demo-crossapp/crossapp-client/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-crossapp - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT crossapp-client Java Chassis::Demo::CrossApp::Client @@ -42,24 +42,88 @@ crossapp-server + + + + io.fabric8 + docker-maven-plugin + + + + servicecomb/service-center + service-center + + + server is ready + + + 30100 + + + + + + 30100:30100 + + + + + ${demo.service.name}:${project.version} + ${demo.service.name} + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/${demo.service.name}-${project.version}.jar + + + service-center:sc.servicecomb.io + + + ServiceComb is ready + + + 8080 + + + + + + 7070:7070 + 8080:8080 + + + service-center + + + + + + + + start + pre-integration-test + + start + + + + stop + post-integration-test + + stop + + + + + + io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config - ${project.version} - - - - diff --git a/demo/demo-crossapp/crossapp-server/pom.xml b/demo/demo-crossapp/crossapp-server/pom.xml index e6f0fefed94..0207bdb7b20 100644 --- a/demo/demo-crossapp/crossapp-server/pom.xml +++ b/demo/demo-crossapp/crossapp-server/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-crossapp - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT crossapp-server Java Chassis::Demo::CrossApp::Server @@ -47,28 +47,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-crossapp/pom.xml b/demo/demo-crossapp/pom.xml index 2e265b2a209..08c2055d357 100644 --- a/demo/demo-crossapp/pom.xml +++ b/demo/demo-crossapp/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-crossapp Java Chassis::Demo::CrossApp diff --git a/demo/demo-cse-v1/consumer/pom.xml b/demo/demo-cse-v1/consumer/pom.xml index 61b3d8baad4..78a7bf75a23 100644 --- a/demo/demo-cse-v1/consumer/pom.xml +++ b/demo/demo-cse-v1/consumer/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-cse-v1 - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT cse-v1-consumer diff --git a/demo/demo-cse-v1/consumer/src/main/resources/application.yml b/demo/demo-cse-v1/consumer/src/main/resources/application.yml index aa66a2ec7c8..11f739de444 100644 --- a/demo/demo-cse-v1/consumer/src/main/resources/application.yml +++ b/demo/demo-cse-v1/consumer/src/main/resources/application.yml @@ -135,4 +135,3 @@ servicecomb: secretKey: ${CREDENTIALS_SK} akskCustomCipher: default project: cn-south-1 - diff --git a/demo/demo-cse-v1/gateway/pom.xml b/demo/demo-cse-v1/gateway/pom.xml index bab44142980..49241e669cf 100644 --- a/demo/demo-cse-v1/gateway/pom.xml +++ b/demo/demo-cse-v1/gateway/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-cse-v1 - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT cse-v1-gateway diff --git a/demo/demo-cse-v1/pom.xml b/demo/demo-cse-v1/pom.xml index 62484bfb0ac..72e70e58c15 100644 --- a/demo/demo-cse-v1/pom.xml +++ b/demo/demo-cse-v1/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-cse-v1 Java Chassis::Demo::CSE-V1 diff --git a/demo/demo-cse-v1/provider-canary/pom.xml b/demo/demo-cse-v1/provider-canary/pom.xml index ed59d023c76..34c393b9e8d 100644 --- a/demo/demo-cse-v1/provider-canary/pom.xml +++ b/demo/demo-cse-v1/provider-canary/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-cse-v1 - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT cse-v1-provider-canary diff --git a/demo/demo-cse-v1/provider/pom.xml b/demo/demo-cse-v1/provider/pom.xml index ef2b38a0d59..12015bd6b7a 100644 --- a/demo/demo-cse-v1/provider/pom.xml +++ b/demo/demo-cse-v1/provider/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-cse-v1 - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT cse-v1-provider diff --git a/demo/demo-cse-v1/test-client/pom.xml b/demo/demo-cse-v1/test-client/pom.xml index ff9c2478ffd..697c28fb64e 100644 --- a/demo/demo-cse-v1/test-client/pom.xml +++ b/demo/demo-cse-v1/test-client/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-cse-v1 - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT cse-v1-test-client diff --git a/demo/demo-cse-v2/consumer/pom.xml b/demo/demo-cse-v2/consumer/pom.xml index ccdfa1ebca3..0fe6e05f4d0 100644 --- a/demo/demo-cse-v2/consumer/pom.xml +++ b/demo/demo-cse-v2/consumer/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-cse-v2 - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT cse-v2-consumer diff --git a/demo/demo-cse-v2/gateway/pom.xml b/demo/demo-cse-v2/gateway/pom.xml index 32a0e463874..1d04a248410 100644 --- a/demo/demo-cse-v2/gateway/pom.xml +++ b/demo/demo-cse-v2/gateway/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-cse-v2 - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT cse-v2-gateway diff --git a/demo/demo-cse-v2/pom.xml b/demo/demo-cse-v2/pom.xml index 003799598e2..35a623930da 100644 --- a/demo/demo-cse-v2/pom.xml +++ b/demo/demo-cse-v2/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-cse-v2 Java Chassis::Demo::CSE-V2 diff --git a/demo/demo-cse-v2/provider/pom.xml b/demo/demo-cse-v2/provider/pom.xml index c090891c6f6..4308b1169d9 100644 --- a/demo/demo-cse-v2/provider/pom.xml +++ b/demo/demo-cse-v2/provider/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-cse-v2 - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT cse-v2-provider diff --git a/demo/demo-cse-v2/test-client/pom.xml b/demo/demo-cse-v2/test-client/pom.xml index 6edd193e6ee..78917aa7e5c 100644 --- a/demo/demo-cse-v2/test-client/pom.xml +++ b/demo/demo-cse-v2/test-client/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-cse-v2 - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT cse-v2-test-client diff --git a/demo/demo-edge/README.md b/demo/demo-edge/README.md index 60a3bbf119c..b5a552e0668 100644 --- a/demo/demo-edge/README.md +++ b/demo/demo-edge/README.md @@ -15,5 +15,3 @@ * 2.0.0: /business/v1/add, /business/v1/dec, /business/v2/add, /business/v2/dec 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. - - diff --git a/demo/demo-edge/authentication/pom.xml b/demo/demo-edge/authentication/pom.xml index 5edd0dbeac7..4849faf28fe 100644 --- a/demo/demo-edge/authentication/pom.xml +++ b/demo/demo-edge/authentication/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb.demo demo-edge - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT authentication Java Chassis::Demo::Edge::Authentication @@ -43,28 +43,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-edge/business-1-1-0/pom.xml b/demo/demo-edge/business-1-1-0/pom.xml index 9186d30dfb5..1cef9b01cab 100644 --- a/demo/demo-edge/business-1-1-0/pom.xml +++ b/demo/demo-edge/business-1-1-0/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb.demo demo-edge - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT business-1-1-0 Java Chassis::Demo::Edge::Business 1.1.0 @@ -49,28 +49,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-edge/business-1.0.0/pom.xml b/demo/demo-edge/business-1.0.0/pom.xml index 62619c775ea..d7e35748fef 100644 --- a/demo/demo-edge/business-1.0.0/pom.xml +++ b/demo/demo-edge/business-1.0.0/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-edge - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT business-1-0-0 Java Chassis::Demo::Edge::Business 1.0.0 @@ -51,28 +51,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-edge/business-2.0.0/pom.xml b/demo/demo-edge/business-2.0.0/pom.xml index 841eb152121..3500be47d75 100644 --- a/demo/demo-edge/business-2.0.0/pom.xml +++ b/demo/demo-edge/business-2.0.0/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-edge - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT business-2-0-0 Java Chassis::Demo::Edge::Business 2.0.0 @@ -51,28 +51,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-edge/consumer/pom.xml b/demo/demo-edge/consumer/pom.xml index 0cd698cc8c3..c26ca048528 100644 --- a/demo/demo-edge/consumer/pom.xml +++ b/demo/demo-edge/consumer/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-edge - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT consumer Java Chassis::Demo::Edge::Consumer @@ -47,24 +47,212 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + servicecomb/service-center + service-center + + + server is ready + + + 30100 + + + + + + 30100:30100 + + + + + authentication:${project.version} + authentication + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/authentication-${project.version}.jar + + + service-center:sc.servicecomb.io + + + ServiceComb is ready + + + 7070 + + + + + + 7070:7070 + + + service-center + + + + + business-1-0-0:${project.version} + business-1-0-0 + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/business-1-0-0-${project.version}.jar + + + service-center:sc.servicecomb.io + + + ServiceComb is ready + + + 8080 + + + + + + 8080:8080 + + + service-center + + + + + business-1-1-0:${project.version} + business-1-1-0 + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/business-1-1-0-${project.version}.jar + + + service-center:sc.servicecomb.io + + + ServiceComb is ready + + + 8090 + + + + + + 8090:8090 + + + service-center + + + + + business-2-0-0:${project.version} + business-2-0-0 + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/business-2-0-0-${project.version}.jar + + + service-center:sc.servicecomb.io + + + Register microservice instance success + + + 8091 + + + + + + 8091:8091 + + + service-center + + + + + edge-service:${project.version} + edge-service + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/edge-service-${project.version}.jar + + + service-center:sc.servicecomb.io + + + Register microservice instance success + + + + 18090 + + + + + + 18090:18090 + + + service-center + + + + + + + + start + pre-integration-test + + start + + + + stop + post-integration-test + + stop + + + + + + io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config-edge - ${project.version} - - - - diff --git a/demo/demo-edge/edge-service/pom.xml b/demo/demo-edge/edge-service/pom.xml index c827fb8b7fd..31fdcff3874 100644 --- a/demo/demo-edge/edge-service/pom.xml +++ b/demo/demo-edge/edge-service/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb.demo demo-edge - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT edge-service Java Chassis::Demo::Edge::Service @@ -49,28 +49,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-edge/model/pom.xml b/demo/demo-edge/model/pom.xml index 4e09f158890..3adda2c13e4 100644 --- a/demo/demo-edge/model/pom.xml +++ b/demo/demo-edge/model/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-edge - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT model Java Chassis::Demo::Edge::Model diff --git a/demo/demo-edge/pom.xml b/demo/demo-edge/pom.xml index 75f0b639781..34cdcd1fccc 100644 --- a/demo/demo-edge/pom.xml +++ b/demo/demo-edge/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-edge Java Chassis::Demo::Edge diff --git a/demo/demo-etcd/consumer/pom.xml b/demo/demo-etcd/consumer/pom.xml index 5f79529d65c..20a03319d43 100644 --- a/demo/demo-etcd/consumer/pom.xml +++ b/demo/demo-etcd/consumer/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-etcd - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT etcd-consumer @@ -44,6 +44,10 @@ org.apache.servicecomb registry-etcd + + org.apache.servicecomb + config-etcd + @@ -59,28 +63,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-etcd/consumer/src/main/resources/application.yml b/demo/demo-etcd/consumer/src/main/resources/application.yml index a63a165189e..e0db5f1434e 100644 --- a/demo/demo-etcd/consumer/src/main/resources/application.yml +++ b/demo/demo-etcd/consumer/src/main/resources/application.yml @@ -25,6 +25,9 @@ servicecomb: registry: etcd: connectString: http://127.0.0.1:2379 + config: + etcd: + connectString: http://127.0.0.1:2379 rest: address: 0.0.0.0:9092?websocketEnabled=true diff --git a/demo/demo-etcd/gateway/pom.xml b/demo/demo-etcd/gateway/pom.xml index 9bed75de856..0b52381a492 100644 --- a/demo/demo-etcd/gateway/pom.xml +++ b/demo/demo-etcd/gateway/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-etcd - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT etcd-gateway @@ -62,28 +62,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-etcd/pom.xml b/demo/demo-etcd/pom.xml index bda7b06fe8c..c615edd88b1 100644 --- a/demo/demo-etcd/pom.xml +++ b/demo/demo-etcd/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-etcd Java Chassis::Demo::Etcd diff --git a/demo/demo-etcd/provider/pom.xml b/demo/demo-etcd/provider/pom.xml index cc926bda1ce..8d8c005a1e1 100644 --- a/demo/demo-etcd/provider/pom.xml +++ b/demo/demo-etcd/provider/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-etcd - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT etcd-provider @@ -72,28 +72,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java b/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java index 5f4f9719ca8..3bc88c64ac5 100644 --- a/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java +++ b/demo/demo-etcd/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java @@ -48,12 +48,10 @@ public void websocket(ServerWebSocket serverWebsocket) { e.printStackTrace(); } - serverWebsocket.writeTextMessage("hello", r -> { - }); + serverWebsocket.writeTextMessage("hello"); for (int i = 0; i < 5; i++) { - serverWebsocket.writeTextMessage("hello " + i, r -> { - }); + serverWebsocket.writeTextMessage("hello " + i); try { Thread.sleep(500); } catch (InterruptedException e) { diff --git a/demo/demo-etcd/test-client/pom.xml b/demo/demo-etcd/test-client/pom.xml index d14d1b1c45f..ab839d762f5 100644 --- a/demo/demo-etcd/test-client/pom.xml +++ b/demo/demo-etcd/test-client/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-etcd - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT etcd-test-client @@ -128,6 +128,7 @@ -Dservicecomb.registry.etcd.connectString=http://etcd:2379 + -Dservicecomb.config.etcd.connectString=http://etcd:2379 /maven/maven/etcd-consumer-${project.version}.jar @@ -203,19 +204,6 @@ io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config - ${project.version} - - - - diff --git a/demo/demo-etcd/test-client/src/main/resources/application.yml b/demo/demo-etcd/test-client/src/main/resources/application.yml index 4245a4d2c86..adcf259e984 100644 --- a/demo/demo-etcd/test-client/src/main/resources/application.yml +++ b/demo/demo-etcd/test-client/src/main/resources/application.yml @@ -33,5 +33,3 @@ test2: applition test3: service test4: version test5: tag - - diff --git a/demo/demo-filter/filter-client/pom.xml b/demo/demo-filter/filter-client/pom.xml index 42e9c6af073..6c39fb4f5ad 100644 --- a/demo/demo-filter/filter-client/pom.xml +++ b/demo/demo-filter/filter-client/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-filter - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT filter-client Java Chassis::Demo::Filter::Client @@ -56,28 +56,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-filter/filter-edge/pom.xml b/demo/demo-filter/filter-edge/pom.xml index 6f6d63a47ce..798f7b7697e 100644 --- a/demo/demo-filter/filter-edge/pom.xml +++ b/demo/demo-filter/filter-edge/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-filter - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT filter-edge Java Chassis::Demo::Filter::Edge @@ -60,28 +60,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-filter/filter-server/pom.xml b/demo/demo-filter/filter-server/pom.xml index 3710a3efb7b..b3f257fd875 100644 --- a/demo/demo-filter/filter-server/pom.xml +++ b/demo/demo-filter/filter-server/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-filter - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT filter-server Java Chassis::Demo::Filter::Server @@ -51,28 +51,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-filter/filter-tests/pom.xml b/demo/demo-filter/filter-tests/pom.xml index b9d33164b31..3936a85f517 100644 --- a/demo/demo-filter/filter-tests/pom.xml +++ b/demo/demo-filter/filter-tests/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-filter - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT filter-tests Java Chassis::Demo::Filter::Tests @@ -184,19 +184,6 @@ io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config - ${project.version} - - - - diff --git a/demo/demo-filter/pom.xml b/demo/demo-filter/pom.xml index 02357f17c6b..45e0206faf1 100644 --- a/demo/demo-filter/pom.xml +++ b/demo/demo-filter/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-filter Java Chassis::Demo::Filter diff --git a/demo/demo-jaxrs/jaxrs-client/pom.xml b/demo/demo-jaxrs/jaxrs-client/pom.xml index 7ded2d60e8b..d25a3cdecca 100644 --- a/demo/demo-jaxrs/jaxrs-client/pom.xml +++ b/demo/demo-jaxrs/jaxrs-client/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-jaxrs - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT jaxrs-client Java Chassis::Demo::JAXRS::Client @@ -45,24 +45,88 @@ jaxrs-server + + + + io.fabric8 + docker-maven-plugin + + + + servicecomb/service-center + service-center + + + server is ready + + + 30100 + + + + + + 30100:30100 + + + + + ${demo.service.name}:${project.version} + ${demo.service.name} + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/${demo.service.name}-${project.version}.jar + + + service-center:sc.servicecomb.io + + + ServiceComb is ready + + + 8080 + + + + + + 7070:7070 + 8080:8080 + + + service-center + + + + + + + + start + pre-integration-test + + start + + + + stop + post-integration-test + + stop + + + + + + io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config - ${project.version} - - - - diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java index 5d919a5bfab..66c5ab958b4 100644 --- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java +++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java @@ -57,6 +57,6 @@ private void test404(RestOperations template) { } } TestMgr.check(404, exception.getStatusCode().value()); - TestMgr.check("404 Not Found: \"{\"message\":\"Not Found\"}\"", exception.getMessage()); + TestMgr.check(true, exception.getMessage().contains("404 Not Found")); } } diff --git a/demo/demo-jaxrs/jaxrs-server/pom.xml b/demo/demo-jaxrs/jaxrs-server/pom.xml index 41f99ae1c6a..cc80ad1521c 100644 --- a/demo/demo-jaxrs/jaxrs-server/pom.xml +++ b/demo/demo-jaxrs/jaxrs-server/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-jaxrs - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT jaxrs-server Java Chassis::Demo::JAXRS::Server @@ -61,28 +61,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-jaxrs/pom.xml b/demo/demo-jaxrs/pom.xml index 1e21f87deee..014baac0318 100644 --- a/demo/demo-jaxrs/pom.xml +++ b/demo/demo-jaxrs/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-jaxrs Java Chassis::Demo::JAXRS diff --git a/demo/demo-local-registry/demo-local-registry-client/pom.xml b/demo/demo-local-registry/demo-local-registry-client/pom.xml index 587b1bfe56c..352e0cf26aa 100644 --- a/demo/demo-local-registry/demo-local-registry-client/pom.xml +++ b/demo/demo-local-registry/demo-local-registry-client/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-local-registry - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -45,24 +45,60 @@ demo-local-registry-server + + + + io.fabric8 + docker-maven-plugin + + + + ${demo.service.name}:${project.version} + ${demo.service.name} + + + /maven/maven/${demo.service.name}-${project.version}.jar + + + ServiceComb is ready + + + 8080 + + + + + + 8080:8080 + + + + + + + + start + pre-integration-test + + start + + + + stop + post-integration-test + + stop + + + + + + io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config-local - ${project.version} - - - - diff --git a/demo/demo-local-registry/demo-local-registry-server/pom.xml b/demo/demo-local-registry/demo-local-registry-server/pom.xml index c9a0055690c..8832ac2dc8a 100644 --- a/demo/demo-local-registry/demo-local-registry-server/pom.xml +++ b/demo/demo-local-registry/demo-local-registry-server/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-local-registry - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -55,28 +55,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-local-registry/pom.xml b/demo/demo-local-registry/pom.xml index b987d28f272..c33eebf22e7 100644 --- a/demo/demo-local-registry/pom.xml +++ b/demo/demo-local-registry/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-local-registry Java Chassis::Demo::Local Registry diff --git a/demo/demo-multi-registries/demo-multi-registries-client/pom.xml b/demo/demo-multi-registries/demo-multi-registries-client/pom.xml index 63fa50d7d43..3577950317f 100644 --- a/demo/demo-multi-registries/demo-multi-registries-client/pom.xml +++ b/demo/demo-multi-registries/demo-multi-registries-client/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-multi-registries - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -45,24 +45,88 @@ demo-multi-registries-server + + + + io.fabric8 + docker-maven-plugin + + + + servicecomb/service-center + service-center + + + server is ready + + + 30100 + + + + + + 30100:30100 + + + + + ${demo.service.name}:${project.version} + ${demo.service.name} + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/${demo.service.name}-${project.version}.jar + + + service-center:sc.servicecomb.io + + + ServiceComb is ready + + + 8080 + + + + + + 7070:7070 + 8080:8080 + + + service-center + + + + + + + + start + pre-integration-test + + start + + + + stop + post-integration-test + + stop + + + + + + io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config - ${project.version} - - - - diff --git a/demo/demo-multi-registries/demo-multi-registries-server/pom.xml b/demo/demo-multi-registries/demo-multi-registries-server/pom.xml index 2418d2994e9..4a0b37f4433 100644 --- a/demo/demo-multi-registries/demo-multi-registries-server/pom.xml +++ b/demo/demo-multi-registries/demo-multi-registries-server/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-multi-registries - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -55,28 +55,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-multi-registries/pom.xml b/demo/demo-multi-registries/pom.xml index 021ed4aa273..13f34c9c7af 100644 --- a/demo/demo-multi-registries/pom.xml +++ b/demo/demo-multi-registries/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-multi-registries Java Chassis::Demo::Multi Registry diff --git a/demo/demo-multi-service-center/demo-multi-service-center-client/pom.xml b/demo/demo-multi-service-center/demo-multi-service-center-client/pom.xml index ecdbfedbff6..2669f28a874 100644 --- a/demo/demo-multi-service-center/demo-multi-service-center-client/pom.xml +++ b/demo/demo-multi-service-center/demo-multi-service-center-client/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-multi-service-center - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -177,21 +177,6 @@ io.fabric8 docker-maven-plugin - - org.apache.maven.plugins - maven-failsafe-plugin - - ${jacoco.failsafe.argLine} - - - - - integration-test - verify - - - - diff --git a/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java b/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java index 85f041034cf..3b11e0582d8 100644 --- a/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java +++ b/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java @@ -42,6 +42,8 @@ import org.apache.servicecomb.service.center.client.model.MicroserviceInstance; import org.apache.servicecomb.service.center.client.model.SchemaInfo; import org.apache.servicecomb.service.center.client.model.ServiceCenterConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import com.google.common.base.Charsets; @@ -58,14 +60,21 @@ public class RegistryClientTest implements CategorizedTestCase { // auto test only tests 'hasRegistered=false', can run this client many times to test 'hasRegistered=true' private boolean hasRegistered = true; + private final Environment environment; + + @Autowired + public RegistryClientTest(Environment environment) { + this.environment = environment; + } + @Override public void testRestTransport() throws Exception { - ServiceCenterAddressManager addressManager = new ServiceCenterAddressManager("default", Arrays.asList("http://127.0.0.1:30100"), - new EventBus()); + ServiceCenterAddressManager addressManager = new ServiceCenterAddressManager("default", + Arrays.asList("http://127.0.0.1:30100"), new EventBus(), "", ""); SSLProperties sslProperties = new SSLProperties(); sslProperties.setEnabled(false); ServiceCenterClient serviceCenterClient = new ServiceCenterClient(addressManager, sslProperties, - new DefaultRequestAuthHeaderProvider(), "default", null); + new DefaultRequestAuthHeaderProvider(), "default", null, environment); EventBus eventBus = new SimpleEventBus(); ServiceCenterConfiguration serviceCenterConfiguration = new ServiceCenterConfiguration(); ServiceCenterRegistration serviceCenterRegistration = new ServiceCenterRegistration(serviceCenterClient, diff --git a/demo/demo-multi-service-center/demo-multi-service-center-serverA/pom.xml b/demo/demo-multi-service-center/demo-multi-service-center-serverA/pom.xml index 0455b6e6942..ddfd3570a43 100644 --- a/demo/demo-multi-service-center/demo-multi-service-center-serverA/pom.xml +++ b/demo/demo-multi-service-center/demo-multi-service-center-serverA/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-multi-service-center - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -55,28 +55,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-multi-service-center/demo-multi-service-center-serverB/pom.xml b/demo/demo-multi-service-center/demo-multi-service-center-serverB/pom.xml index 6d860cf5e39..66dfd58d9b4 100644 --- a/demo/demo-multi-service-center/demo-multi-service-center-serverB/pom.xml +++ b/demo/demo-multi-service-center/demo-multi-service-center-serverB/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-multi-service-center - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -55,28 +55,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-multi-service-center/pom.xml b/demo/demo-multi-service-center/pom.xml index 731e09c3f53..cf9c101e496 100644 --- a/demo/demo-multi-service-center/pom.xml +++ b/demo/demo-multi-service-center/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-multi-service-center Java Chassis::Demo::Multi Service Centers diff --git a/demo/demo-multiple/a-client/pom.xml b/demo/demo-multiple/a-client/pom.xml index 814039b63e6..84131a7909c 100644 --- a/demo/demo-multiple/a-client/pom.xml +++ b/demo/demo-multiple/a-client/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-multiple - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT a-client Java Chassis::Demo::Multiple::A client diff --git a/demo/demo-multiple/a-server/pom.xml b/demo/demo-multiple/a-server/pom.xml index ad78ef365e7..d38b12d8d62 100644 --- a/demo/demo-multiple/a-server/pom.xml +++ b/demo/demo-multiple/a-server/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-multiple - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT a-server Java Chassis::Demo::Multiple::A server diff --git a/demo/demo-multiple/b-client/pom.xml b/demo/demo-multiple/b-client/pom.xml index 02f0a1f4e7e..4ab02a66f1b 100644 --- a/demo/demo-multiple/b-client/pom.xml +++ b/demo/demo-multiple/b-client/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-multiple - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT b-client Java Chassis::Demo::Multiple::B client diff --git a/demo/demo-multiple/b-server/pom.xml b/demo/demo-multiple/b-server/pom.xml index 14c88f684b2..e33e750d8e4 100644 --- a/demo/demo-multiple/b-server/pom.xml +++ b/demo/demo-multiple/b-server/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-multiple - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT b-server diff --git a/demo/demo-multiple/multiple-client/pom.xml b/demo/demo-multiple/multiple-client/pom.xml index d337063412b..7dcbb6f14f2 100644 --- a/demo/demo-multiple/multiple-client/pom.xml +++ b/demo/demo-multiple/multiple-client/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-multiple - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT multiple-client Java Chassis::Demo::Multiple::Client @@ -48,24 +48,88 @@ multiple-server + + + + io.fabric8 + docker-maven-plugin + + + + servicecomb/service-center + service-center + + + server is ready + + + 30100 + + + + + + 30100:30100 + + + + + ${demo.service.name}:${project.version} + ${demo.service.name} + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/${demo.service.name}-${project.version}.jar + + + service-center:sc.servicecomb.io + + + ServiceComb is ready + + + 8080 + + + + + + 7070:7070 + 8080:8080 + + + service-center + + + + + + + + start + pre-integration-test + + start + + + + stop + post-integration-test + + stop + + + + + + io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config - ${project.version} - - - - diff --git a/demo/demo-multiple/multiple-server/pom.xml b/demo/demo-multiple/multiple-server/pom.xml index 21f04a24735..18c7ae19069 100644 --- a/demo/demo-multiple/multiple-server/pom.xml +++ b/demo/demo-multiple/multiple-server/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-multiple - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT multiple-server Java Chassis::Demo::Multiple::Server @@ -54,28 +54,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-multiple/pom.xml b/demo/demo-multiple/pom.xml index 59b75d6a571..7496a2050d7 100644 --- a/demo/demo-multiple/pom.xml +++ b/demo/demo-multiple/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-multiple Java Chassis::Demo::Multiple diff --git a/demo/demo-nacos/consumer/pom.xml b/demo/demo-nacos/consumer/pom.xml index f5b2cafa83a..6dfe326f6a5 100644 --- a/demo/demo-nacos/consumer/pom.xml +++ b/demo/demo-nacos/consumer/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-nacos - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT nacos-consumer @@ -53,28 +53,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-nacos/gateway/pom.xml b/demo/demo-nacos/gateway/pom.xml index c04739ea577..f76d407973a 100644 --- a/demo/demo-nacos/gateway/pom.xml +++ b/demo/demo-nacos/gateway/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-nacos - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT nacos-gateway @@ -56,28 +56,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-nacos/pom.xml b/demo/demo-nacos/pom.xml index 642ad561bd4..a37e292de1d 100644 --- a/demo/demo-nacos/pom.xml +++ b/demo/demo-nacos/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-nacos Java Chassis::Demo::NACOS diff --git a/demo/demo-nacos/provider/pom.xml b/demo/demo-nacos/provider/pom.xml index 282f2b0325a..a23bc1bb06f 100644 --- a/demo/demo-nacos/provider/pom.xml +++ b/demo/demo-nacos/provider/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-nacos - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT nacos-provider @@ -57,28 +57,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-nacos/test-client/pom.xml b/demo/demo-nacos/test-client/pom.xml index 638ad53689c..103aeb24d94 100644 --- a/demo/demo-nacos/test-client/pom.xml +++ b/demo/demo-nacos/test-client/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-nacos - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT nacos-test-client @@ -193,19 +193,6 @@ io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config - ${project.version} - - - - diff --git a/demo/demo-pojo/pojo-client/pom.xml b/demo/demo-pojo/pojo-client/pom.xml index d9fbcab8cd1..582c8c8f511 100644 --- a/demo/demo-pojo/pojo-client/pom.xml +++ b/demo/demo-pojo/pojo-client/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-pojo - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT pojo-client Java Chassis::Demo::POJO::Client @@ -54,24 +54,88 @@ pojo-server + + + + io.fabric8 + docker-maven-plugin + + + + servicecomb/service-center + service-center + + + server is ready + + + 30100 + + + + + + 30100:30100 + + + + + ${demo.service.name}:${project.version} + ${demo.service.name} + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/${demo.service.name}-${project.version}.jar + + + service-center:sc.servicecomb.io + + + ServiceComb is ready + + + 8080 + + + + + + 7070:7070 + 8080:8080 + + + service-center + + + + + + + + start + pre-integration-test + + start + + + + stop + post-integration-test + + stop + + + + + + io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config - ${project.version} - - - - diff --git a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClient.java b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClient.java index 7d3386fa38c..601901e5884 100644 --- a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClient.java +++ b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClient.java @@ -94,7 +94,7 @@ private void testCodeFirstCompletableFuture(CodeFirstPojoIntf codeFirst) { return; } - Vertx vertx = VertxUtils.getOrCreateVertxByName("transport", null); + Vertx vertx = VertxUtils.getOrCreateVertxByName("transport", null, null); CountDownLatch latch = new CountDownLatch(1); // vertx.runOnContext in normal thread is not a good practice // here just a test, not care for this. diff --git a/demo/demo-pojo/pojo-server/pom.xml b/demo/demo-pojo/pojo-server/pom.xml index b8c6757057a..b0b673ef47e 100644 --- a/demo/demo-pojo/pojo-server/pom.xml +++ b/demo/demo-pojo/pojo-server/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-pojo - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT pojo-server Java Chassis::Demo::POJO::Server @@ -36,7 +36,9 @@ org.apache.servicecomb.demo.pojo.server.PojoServer + true + @@ -49,28 +51,51 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-pojo/pom.xml b/demo/demo-pojo/pom.xml index 21c69591df5..96217173a03 100644 --- a/demo/demo-pojo/pom.xml +++ b/demo/demo-pojo/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-pojo Java Chassis::Demo::POJO diff --git a/demo/demo-register-url-prefix/demo-register-url-prefix-client/pom.xml b/demo/demo-register-url-prefix/demo-register-url-prefix-client/pom.xml index d1d1859ba8d..1b7fc782cd1 100644 --- a/demo/demo-register-url-prefix/demo-register-url-prefix-client/pom.xml +++ b/demo/demo-register-url-prefix/demo-register-url-prefix-client/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-register-url-prefix - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -45,24 +45,88 @@ demo-register-url-prefix-server + + + + io.fabric8 + docker-maven-plugin + + + + servicecomb/service-center + service-center + + + server is ready + + + 30100 + + + + + + 30100:30100 + + + + + ${demo.service.name}:${project.version} + ${demo.service.name} + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/${demo.service.name}-${project.version}.jar + + + service-center:sc.servicecomb.io + + + ServiceComb is ready + + + 8080 + + + + + + 7070:7070 + 8080:8080 + + + service-center + + + + + + + + start + pre-integration-test + + start + + + + stop + post-integration-test + + stop + + + + + + io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config - ${project.version} - - - - diff --git a/demo/demo-register-url-prefix/demo-register-url-prefix-server/pom.xml b/demo/demo-register-url-prefix/demo-register-url-prefix-server/pom.xml index cd46fbe600b..2d34ae62051 100644 --- a/demo/demo-register-url-prefix/demo-register-url-prefix-server/pom.xml +++ b/demo/demo-register-url-prefix/demo-register-url-prefix-server/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-register-url-prefix - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -50,28 +50,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-register-url-prefix/pom.xml b/demo/demo-register-url-prefix/pom.xml index d4042f8d47b..e51630b5397 100644 --- a/demo/demo-register-url-prefix/pom.xml +++ b/demo/demo-register-url-prefix/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-register-url-prefix Java Chassis::Demo::Register URL Prefix diff --git a/demo/demo-schema/pom.xml b/demo/demo-schema/pom.xml index 0f386431b77..b17f345111b 100644 --- a/demo/demo-schema/pom.xml +++ b/demo/demo-schema/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-schema Java Chassis::Demo::Schema diff --git a/demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/pom.xml b/demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/pom.xml index 776a577c870..372d3a8ccc3 100644 --- a/demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/pom.xml +++ b/demo/demo-spring-boot-transport/demo-spring-boot-pojo-client/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-spring-boot-transport - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -39,24 +39,88 @@ demo-spring-boot-pojo-server + + + + io.fabric8 + docker-maven-plugin + + + + servicecomb/service-center + service-center + + + server is ready + + + 30100 + + + + + + 30100:30100 + + + + + ${demo.service.name}:${project.version} + ${demo.service.name} + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/${demo.service.name}-${project.version}.jar + + + service-center:sc.servicecomb.io + + + ServiceComb is ready + + + 8080 + + + + + + 7070:7070 + 8080:8080 + + + service-center + + + + + + + + start + pre-integration-test + + start + + + + stop + post-integration-test + + stop + + + + + + io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config - ${project.version} - - - - diff --git a/demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/pom.xml b/demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/pom.xml index 572394627d2..60761704af9 100644 --- a/demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/pom.xml +++ b/demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-spring-boot-transport - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -52,28 +52,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/pom.xml b/demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/pom.xml index b6afa72ef5a..edd73c1428b 100644 --- a/demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/pom.xml +++ b/demo/demo-spring-boot-transport/demo-spring-boot-springmvc-client/pom.xml @@ -26,7 +26,7 @@ org.apache.servicecomb.demo demo-spring-boot-transport - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -42,24 +42,88 @@ demo-spring-boot-springmvc-server + + + + io.fabric8 + docker-maven-plugin + + + + servicecomb/service-center + service-center + + + server is ready + + + 30100 + + + + + + 30100:30100 + + + + + ${demo.service.name}:${project.version} + ${demo.service.name} + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/${demo.service.name}-${project.version}.jar + + + service-center:sc.servicecomb.io + + + ServiceComb is ready + + + 8080 + + + + + + 7070:7070 + 8080:8080 + + + service-center + + + + + + + + start + pre-integration-test + + start + + + + stop + post-integration-test + + stop + + + + + + io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config - ${project.version} - - - - diff --git a/demo/demo-spring-boot-transport/demo-spring-boot-springmvc-server/pom.xml b/demo/demo-spring-boot-transport/demo-spring-boot-springmvc-server/pom.xml index 5fb051ba1ef..efa0723b59a 100644 --- a/demo/demo-spring-boot-transport/demo-spring-boot-springmvc-server/pom.xml +++ b/demo/demo-spring-boot-transport/demo-spring-boot-springmvc-server/pom.xml @@ -26,7 +26,7 @@ org.apache.servicecomb.demo demo-spring-boot-transport - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -47,28 +47,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-spring-boot-transport/pom.xml b/demo/demo-spring-boot-transport/pom.xml index 5fcd9fa6c72..bd7650a3f26 100644 --- a/demo/demo-spring-boot-transport/pom.xml +++ b/demo/demo-spring-boot-transport/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-spring-boot-transport Java Chassis::Demo::Spring Boot::Transport diff --git a/demo/demo-springmvc/pom.xml b/demo/demo-springmvc/pom.xml index 906b6a953c6..c307aa7741b 100644 --- a/demo/demo-springmvc/pom.xml +++ b/demo/demo-springmvc/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-springmvc Java Chassis::Demo::Spring MVC diff --git a/demo/demo-springmvc/springmvc-client/pom.xml b/demo/demo-springmvc/springmvc-client/pom.xml index fb9f903dfb3..17b7bbcd709 100644 --- a/demo/demo-springmvc/springmvc-client/pom.xml +++ b/demo/demo-springmvc/springmvc-client/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-springmvc - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT springmvc-client Java Chassis::Demo::Spring MVC::Client @@ -42,24 +42,88 @@ springmvc-server + + + + io.fabric8 + docker-maven-plugin + + + + servicecomb/service-center + service-center + + + server is ready + + + 30100 + + + + + + 30100:30100 + + + + + ${demo.service.name}:${project.version} + ${demo.service.name} + + + + -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 + + /maven/maven/${demo.service.name}-${project.version}.jar + + + service-center:sc.servicecomb.io + + + ServiceComb is ready + + + 8080 + + + + + + 7070:7070 + 8080:8080 + + + service-center + + + + + + + + start + pre-integration-test + + start + + + + stop + post-integration-test + + stop + + + + + + io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config - ${project.version} - - - - diff --git a/demo/demo-springmvc/springmvc-server/pom.xml b/demo/demo-springmvc/springmvc-server/pom.xml index 57a8d12600a..f88876261d6 100644 --- a/demo/demo-springmvc/springmvc-server/pom.xml +++ b/demo/demo-springmvc/springmvc-server/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-springmvc - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT springmvc-server Java Chassis::Demo::Spring MVC::Server @@ -51,28 +51,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java index c49d8879d92..36f8518afe4 100644 --- a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java +++ b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java @@ -495,7 +495,7 @@ public Generic> testGenericGenericUser(@RequestBody Generic org.apache.servicecomb.demo demo-zeroconfig-registry - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -62,28 +62,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-zeroconfig-registry/demo-zeroconfig-registry-edge/pom.xml b/demo/demo-zeroconfig-registry/demo-zeroconfig-registry-edge/pom.xml index ebe16ceeec4..c8dcb06893a 100644 --- a/demo/demo-zeroconfig-registry/demo-zeroconfig-registry-edge/pom.xml +++ b/demo/demo-zeroconfig-registry/demo-zeroconfig-registry-edge/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-zeroconfig-registry - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -67,28 +67,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-zeroconfig-registry/demo-zeroconfig-registry-server/pom.xml b/demo/demo-zeroconfig-registry/demo-zeroconfig-registry-server/pom.xml index c5ed74d722e..f69f1118a0a 100644 --- a/demo/demo-zeroconfig-registry/demo-zeroconfig-registry-server/pom.xml +++ b/demo/demo-zeroconfig-registry/demo-zeroconfig-registry-server/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-zeroconfig-registry - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -63,6 +63,45 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 @@ -72,19 +111,6 @@ org.commonjava.maven.plugins directory-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/pom.xml b/demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/pom.xml index 8876f77542b..8c57041ea1d 100644 --- a/demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/pom.xml +++ b/demo/demo-zeroconfig-registry/demo-zeroconfig-registry-tests/pom.xml @@ -25,7 +25,7 @@ org.apache.servicecomb.demo demo-zeroconfig-registry - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT @@ -151,24 +151,8 @@ io.fabric8 docker-maven-plugin - - org.apache.maven.plugins - maven-failsafe-plugin - - ${jacoco.failsafe.argLine} - - - - - integration-test - verify - - - - - diff --git a/demo/demo-zeroconfig-registry/pom.xml b/demo/demo-zeroconfig-registry/pom.xml index f8c20e2589b..bc02525e483 100644 --- a/demo/demo-zeroconfig-registry/pom.xml +++ b/demo/demo-zeroconfig-registry/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-zeroconfig-registry Java Chassis::Demo::ZeroConfig Registry diff --git a/demo/demo-zookeeper/consumer/pom.xml b/demo/demo-zookeeper/consumer/pom.xml index 28857551b91..73fb82a25a3 100644 --- a/demo/demo-zookeeper/consumer/pom.xml +++ b/demo/demo-zookeeper/consumer/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-zookeeper - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT zookeeper-consumer @@ -53,28 +53,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-zookeeper/consumer/src/main/resources/application.yml b/demo/demo-zookeeper/consumer/src/main/resources/application.yml index 80087f7c6fb..100797f83b4 100644 --- a/demo/demo-zookeeper/consumer/src/main/resources/application.yml +++ b/demo/demo-zookeeper/consumer/src/main/resources/application.yml @@ -34,5 +34,3 @@ servicecomb: highway: address: 0.0.0.0:7092 - - diff --git a/demo/demo-zookeeper/gateway/pom.xml b/demo/demo-zookeeper/gateway/pom.xml index b51d04b7a7f..f2676b1ed6d 100644 --- a/demo/demo-zookeeper/gateway/pom.xml +++ b/demo/demo-zookeeper/gateway/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb.demo demo-zookeeper - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT zookeeper-gateway @@ -56,28 +56,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-zookeeper/pom.xml b/demo/demo-zookeeper/pom.xml index a474166f5ce..aa1030de1ec 100644 --- a/demo/demo-zookeeper/pom.xml +++ b/demo/demo-zookeeper/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT demo-zookeeper Java Chassis::Demo::Zookeeper diff --git a/demo/demo-zookeeper/provider/pom.xml b/demo/demo-zookeeper/provider/pom.xml index d49e354a438..3b008bfb000 100644 --- a/demo/demo-zookeeper/provider/pom.xml +++ b/demo/demo-zookeeper/provider/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-zookeeper - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT zookeeper-provider @@ -65,28 +65,50 @@ docker + + + + io.fabric8 + docker-maven-plugin + + + + ${project.artifactId}:${project.version} + ${project.artifactId} + + eclipse-temurin:17-jre-jammy + + 7070 + 8080 + + + tar + ${root.basedir}/assembly/assembly.xml + + + java -Xmx128m $JAVA_OPTS -jar $JAR_PATH + + + + + + + + build + package + + build + + + + + + io.fabric8 docker-maven-plugin - - org.commonjava.maven.plugins - directory-maven-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - ${project.version} - - - - diff --git a/demo/demo-zookeeper/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java b/demo/demo-zookeeper/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java index 5f4f9719ca8..6381ef1d54c 100644 --- a/demo/demo-zookeeper/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java +++ b/demo/demo-zookeeper/provider/src/main/java/org/apache/servicecomb/samples/WebsocketController.java @@ -17,6 +17,8 @@ package org.apache.servicecomb.samples; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.apache.servicecomb.core.CoreConst; @@ -33,27 +35,29 @@ public class WebsocketController { @PostMapping("/websocket") @Transport(name = CoreConst.WEBSOCKET) public void websocket(ServerWebSocket serverWebsocket) { - // Client may have not registered message handler, and messages sent may get lost. - // So we sleep for a while to send message. AtomicInteger receiveCount = new AtomicInteger(0); + CountDownLatch startSend = new CountDownLatch(1); serverWebsocket.textMessageHandler(s -> { + if ("start".equals(s)) { + startSend.countDown(); + serverWebsocket.writeTextMessage("started"); + return; + } receiveCount.getAndIncrement(); }); serverWebsocket.closeHandler((v) -> System.out.println("closed")); new Thread(() -> { try { - Thread.sleep(1000); + startSend.await(30, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } - serverWebsocket.writeTextMessage("hello", r -> { - }); + serverWebsocket.writeTextMessage("hello"); for (int i = 0; i < 5; i++) { - serverWebsocket.writeTextMessage("hello " + i, r -> { - }); + serverWebsocket.writeTextMessage("hello " + i); try { Thread.sleep(500); } catch (InterruptedException e) { diff --git a/demo/demo-zookeeper/test-client/pom.xml b/demo/demo-zookeeper/test-client/pom.xml index 63890b23ac0..e527b630005 100644 --- a/demo/demo-zookeeper/test-client/pom.xml +++ b/demo/demo-zookeeper/test-client/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb.demo demo-zookeeper - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT zookeeper-test-client @@ -189,19 +189,6 @@ io.fabric8 docker-maven-plugin - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-run-config - ${project.version} - - - - diff --git a/demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/WebsocketIT.java b/demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/WebsocketIT.java index ea7a7f45b15..c36f2d16d28 100644 --- a/demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/WebsocketIT.java +++ b/demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/WebsocketIT.java @@ -38,10 +38,15 @@ public class WebsocketIT implements CategorizedTestCase { public void testRestTransport() throws Exception { StringBuffer sb = new StringBuffer(); AtomicBoolean closed = new AtomicBoolean(false); + CountDownLatch latchStarted = new CountDownLatch(1); CountDownLatch latch = new CountDownLatch(1); WebSocket webSocket = websocketClient.websocket(); webSocket.textMessageHandler(s -> { + if ("started".equals(s)) { + latchStarted.countDown(); + return; + } sb.append(s); sb.append(" "); webSocket.writeTextMessage(s); @@ -50,6 +55,17 @@ public void testRestTransport() throws Exception { closed.set(true); latch.countDown(); }); + + webSocket.writeTextMessage("start"); + int i = 0; + for (; i < 10; i++) { + if (!latchStarted.await(3, TimeUnit.SECONDS)) { + webSocket.writeTextMessage("start"); + continue; + } + break; + } + TestMgr.check(i < 10, true); latch.await(30, TimeUnit.SECONDS); TestMgr.check(sb.toString(), "hello hello 0 hello 1 hello 2 hello 3 hello 4 total 6 "); TestMgr.check(closed.get(), true); diff --git a/demo/docker-build-config/pom.xml b/demo/docker-build-config/pom.xml deleted file mode 100644 index 746be574983..00000000000 --- a/demo/docker-build-config/pom.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - demo-parent - org.apache.servicecomb.demo - 3.3.0-SNAPSHOT - - 4.0.0 - - docker-build-config - Java Chassis::Demo::Docker Build Config - pom - - - - - - io.fabric8 - docker-maven-plugin - - - - ${project.artifactId}:${project.version} - ${project.artifactId} - - openjdk:17-alpine - - 7070 - 8080 - - - tar - ${root.basedir}/assembly/assembly.xml - - - java -Xmx128m $JAVA_OPTS -jar $JAR_PATH - - - - - - - - build - package - - build - - - - - - org.commonjava.maven.plugins - directory-maven-plugin - - - directories - - directory-of - - initialize - - root.basedir - - org.apache.servicecomb.demo - demo-parent - - - - - - - - - diff --git a/demo/docker-run-config-edge/pom.xml b/demo/docker-run-config-edge/pom.xml deleted file mode 100644 index 942ba680b84..00000000000 --- a/demo/docker-run-config-edge/pom.xml +++ /dev/null @@ -1,268 +0,0 @@ - - - - - demo-parent - org.apache.servicecomb.demo - 3.3.0-SNAPSHOT - - 4.0.0 - - docker-run-config-edge - Java Chassis::Demo::Docker Run Config - - pom - - - - - - io.fabric8 - docker-maven-plugin - - - - servicecomb/service-center - service-center - - - server is ready - - - 30100 - - - - - - 30100:30100 - - - - - authentication:${project.version} - authentication - - - - -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 - - /maven/maven/authentication-${project.version}.jar - - - service-center:sc.servicecomb.io - - - ServiceComb is ready - - - 7070 - - - - - - 7070:7070 - - - service-center - - - - - business-1-0-0:${project.version} - business-1-0-0 - - - - -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 - - /maven/maven/business-1-0-0-${project.version}.jar - - - service-center:sc.servicecomb.io - - - ServiceComb is ready - - - 8080 - - - - - - 8080:8080 - - - service-center - - - - - business-1-1-0:${project.version} - business-1-1-0 - - - - -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 - - /maven/maven/business-1-1-0-${project.version}.jar - - - service-center:sc.servicecomb.io - - - ServiceComb is ready - - - 8090 - - - - - - 8090:8090 - - - service-center - - - - - business-2-0-0:${project.version} - business-2-0-0 - - - - -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 - - /maven/maven/business-2-0-0-${project.version}.jar - - - service-center:sc.servicecomb.io - - - Register microservice instance success - - - 8091 - - - - - - 8091:8091 - - - service-center - - - - - edge-service:${project.version} - edge-service - - - - -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 - - /maven/maven/edge-service-${project.version}.jar - - - service-center:sc.servicecomb.io - - - Register microservice instance success - - - - 18090 - - - - - - 18090:18090 - - - service-center - - - - - - - - start - pre-integration-test - - start - - - - stop - post-integration-test - - stop - - - - - - - - - - - docker - - - - org.apache.maven.plugins - maven-failsafe-plugin - - ${jacoco.failsafe.argLine} - - - - - integration-test - verify - - - - - - - - - docker-machine - - - - - - - diff --git a/demo/docker-run-config-local/pom.xml b/demo/docker-run-config-local/pom.xml deleted file mode 100644 index 35a23d5cbde..00000000000 --- a/demo/docker-run-config-local/pom.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - demo-parent - org.apache.servicecomb.demo - 3.3.0-SNAPSHOT - - 4.0.0 - - docker-run-config-local - Java Chassis::Demo::Docker Run Config Local - - pom - - - - - - io.fabric8 - docker-maven-plugin - - - - ${demo.service.name}:${project.version} - ${demo.service.name} - - - /maven/maven/${demo.service.name}-${project.version}.jar - - - ServiceComb is ready - - - 8080 - - - - - - 8080:8080 - - - - - - - - start - pre-integration-test - - start - - - - stop - post-integration-test - - stop - - - - - - - - - - - docker - - - - org.apache.maven.plugins - maven-failsafe-plugin - - ${jacoco.failsafe.argLine} - - - - - integration-test - verify - - - - - - - - - docker-machine - - - - - - - diff --git a/demo/docker-run-config/pom.xml b/demo/docker-run-config/pom.xml deleted file mode 100644 index 547f8f4ac6f..00000000000 --- a/demo/docker-run-config/pom.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - - - demo-parent - org.apache.servicecomb.demo - 3.3.0-SNAPSHOT - - 4.0.0 - - docker-run-config - Java Chassis::Demo::Docker Run Config - - pom - - - - - - io.fabric8 - docker-maven-plugin - - - - servicecomb/service-center - service-center - - - server is ready - - - 30100 - - - - - - 30100:30100 - - - - - ${demo.service.name}:${project.version} - ${demo.service.name} - - - - -Dservicecomb.registry.sc.address=http://sc.servicecomb.io:30100 - - /maven/maven/${demo.service.name}-${project.version}.jar - - - service-center:sc.servicecomb.io - - - ServiceComb is ready - - - 8080 - - - - - - 7070:7070 - 8080:8080 - - - service-center - - - - - - - - start - pre-integration-test - - start - - - - stop - post-integration-test - - stop - - - - - - - - - - - docker - - - - org.apache.maven.plugins - maven-failsafe-plugin - - ${jacoco.failsafe.argLine} - - - - - integration-test - verify - - - - - - - - - docker-machine - - - - - - - diff --git a/demo/pom.xml b/demo/pom.xml index fa88e1526bb..d0376883c6b 100644 --- a/demo/pom.xml +++ b/demo/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default org.apache.servicecomb.demo @@ -35,10 +35,6 @@ pom - docker-build-config - docker-run-config - docker-run-config-edge - docker-run-config-local demo-schema demo-pojo demo-filter @@ -56,8 +52,10 @@ demo-cse-v1 demo-cse-v2 demo-nacos - demo-etcd + + demo-zookeeper + demo-consul @@ -141,12 +139,6 @@ - - com.github.odavid.maven.plugins - mixin-maven-plugin - 0.1-alpha-40 - true - org.commonjava.maven.plugins directory-maven-plugin @@ -183,7 +175,59 @@ + + org.commonjava.maven.plugins + directory-maven-plugin + + + directories + + directory-of + + initialize + + root.basedir + + org.apache.servicecomb.demo + demo-parent + + + + + + + + org.commonjava.maven.plugins + directory-maven-plugin + + + + + + docker + + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + ${jacoco.failsafe.argLine} + + + + + integration-test + verify + + + + + + + + diff --git a/dependencies/bom/pom.xml b/dependencies/bom/pom.xml index 16b2dea9845..ed5e1bc91a2 100644 --- a/dependencies/bom/pom.xml +++ b/dependencies/bom/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb java-chassis-dependencies-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT java-chassis-bom @@ -116,6 +116,11 @@ config-zookeeper ${project.version} + + org.apache.servicecomb + config-consul + ${project.version} + @@ -287,6 +292,11 @@ org.apache.servicecomb config-etcd ${project.version} + + + org.apache.servicecomb + registry-consul + ${project.version} diff --git a/dependencies/default/pom.xml b/dependencies/default/pom.xml index 663f8e427e0..22f2190ddd1 100644 --- a/dependencies/default/pom.xml +++ b/dependencies/default/pom.xml @@ -17,12 +17,12 @@ --> + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.apache.servicecomb java-chassis-dependencies-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT java-chassis-dependencies @@ -32,47 +32,45 @@ 1.2.2 - 3.26.3 - 4.2.2 - 6.0.3 - 1.9.4 - 2.18.0 + 3.27.7 + 4.3.0 + 6.3.0 + 1.11.0 + 2.21.0 2.6 - 3.17.0 - 1.3.4 - 1.11.0 - 5.7.1 - 1.0.2 + 3.20.0 + 1.3.5 + 1.15.0 + 5.9.0 + 1.0.3 3.0.2 1.17.12 1.17.13 - 33.3.1-jre + 33.5.0-jre 5.1.0 1.3 2.2.2 - 8.0.1.Final + 9.1.0.Final 4.5.14 1.5.18 - 2.18.2 - 1.5.7 + 2.20.1 + 1.6.0 1.3.2 1 1.5 - 3.1.4 + 4.0.2 1.34 4.13.2 - 5.11.3 + 5.13.4 1.2.17 - 2.24.1 - 3.9.9 - 1.14.1 - 5.14.2 + 2.25.3 + 3.9.12 + 1.16.4 + 5.21.0 5.2.0 5.15.0 - 2.4.3 + 3.1.1 0.3.0 - 4.1.115.Final - 4.12.0 0.16.0 3.23.4 1.8.0 @@ -80,18 +78,18 @@ 1.0.4 1.7.0 2.7.18 - 3.1.10 + 3.1.12 1.0.0 0.13.2 6.0.0 1.7.36 - 2.3 - 6.1.10 - 2.2.26 - 4.5.11 - 3.4.2 + 2.5 + 2.2.41 + 5.0.8 + 3.5.1 3.4.0 - 0.8.4 + 0.8.6 + 1.8.0 ${basedir}/../.. @@ -193,18 +191,6 @@ test - - com.squareup.okhttp3 - okhttp - ${okhttp3.version} - - - - com.squareup.okhttp3 - mockwebserver - ${okhttp3.version} - - commons-beanutils commons-beanutils @@ -229,14 +215,6 @@ ${commons-logging.version} - - io.netty - netty-bom - import - ${netty.version} - pom - - org.apache.maven maven-model @@ -301,27 +279,6 @@ ${reactive-streams.version} - - io.vertx - vertx-codegen - ${vertx.version} - - - io.vertx - vertx-core - ${vertx.version} - - - io.vertx - vertx-web - ${vertx.version} - - - io.vertx - vertx-rx-java3 - ${vertx.version} - - io.zipkin.brave brave-bom @@ -481,13 +438,6 @@ test - - org.mock-server - mockserver-netty - ${mock-server.version} - test - - org.slf4j slf4j-api @@ -495,9 +445,9 @@ - org.springframework - spring-framework-bom - ${spring.version} + io.vertx + vertx-dependencies + ${vertx.version} pom import @@ -549,6 +499,12 @@ jetcd-core ${jetcd-core.version} + + + org.kiwiproject + consul-client + ${consul-client.version} + diff --git a/dependencies/pom.xml b/dependencies/pom.xml index 6382b78897a..4ee9c9ea071 100644 --- a/dependencies/pom.xml +++ b/dependencies/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb java-chassis - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT java-chassis-dependencies-parent diff --git a/distribution/pom.xml b/distribution/pom.xml index d48c3497ea1..ddd1e3de25d 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default apache-servicecomb-java-chassis-distribution diff --git a/dynamic-config/config-apollo/pom.xml b/dynamic-config/config-apollo/pom.xml index fff4c2036ba..7cc03d182dd 100644 --- a/dynamic-config/config-apollo/pom.xml +++ b/dynamic-config/config-apollo/pom.xml @@ -22,7 +22,7 @@ dynamic-config org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 config-apollo diff --git a/dynamic-config/config-cc/pom.xml b/dynamic-config/config-cc/pom.xml index 160e4d578b1..0e8f6addcc6 100644 --- a/dynamic-config/config-cc/pom.xml +++ b/dynamic-config/config-cc/pom.xml @@ -21,7 +21,7 @@ dynamic-config org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterConfig.java b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterConfig.java index eaa047e98bb..c1cf7c1b683 100644 --- a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterConfig.java +++ b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterConfig.java @@ -39,6 +39,12 @@ public final class ConfigCenterConfig { private static final int DEFAULT_REFRESH_INTERVAL = 15000; + private static final String CLIENT_CONNECT_TIMEOUT = "servicecomb.config.client.timeout.connect"; + + private static final String CLIENT_REQUEST_TIMEOUT = "servicecomb.config.client.timeout.request"; + + private static final String CLIENT_SOCKET_TIMEOUT = "servicecomb.config.client.timeout.socket"; + private final Environment environment; public ConfigCenterConfig(Environment environment) { @@ -86,4 +92,16 @@ public String getProxyPasswd() { public List getServerUri() { return ConfigUtil.parseArrayValue(environment.getProperty(ADDRESS, "")); } + + public int getConnectTimeout() { + return environment.getProperty(CLIENT_CONNECT_TIMEOUT, int.class, 5000); + } + + public int getConnectionRequestTimeout() { + return environment.getProperty(CLIENT_REQUEST_TIMEOUT, int.class, 5000); + } + + public int getSocketTimeout() { + return environment.getProperty(CLIENT_SOCKET_TIMEOUT, int.class, 5000); + } } diff --git a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterDynamicPropertiesSource.java b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterDynamicPropertiesSource.java index 431963da6aa..23c0a7af196 100644 --- a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterDynamicPropertiesSource.java +++ b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterDynamicPropertiesSource.java @@ -69,11 +69,10 @@ private void init(Environment environment) { ConfigCenterConfig configCenterConfig = new ConfigCenterConfig(environment); configConverter = new ConfigConverter(configCenterConfig.getFileSources()); - ConfigCenterAddressManager configCenterAddressManager = configCenterAddressManager(configCenterConfig); + ConfigCenterAddressManager configCenterAddressManager = configCenterAddressManager(configCenterConfig, environment); HttpTransport httpTransport = createHttpTransport(configCenterAddressManager, - HttpTransportFactory.defaultRequestConfig().build(), - environment, configCenterConfig); + buildRequestConfig(configCenterConfig), environment, configCenterConfig); ConfigCenterClient configCenterClient = new ConfigCenterClient(configCenterAddressManager, httpTransport); EventManager.register(this); @@ -90,6 +89,14 @@ private void init(Environment environment) { data.putAll(configConverter.getCurrentData()); } + private RequestConfig buildRequestConfig(ConfigCenterConfig config) { + RequestConfig.Builder builder = HttpTransportFactory.defaultRequestConfig(); + builder.setConnectTimeout(config.getConnectTimeout()); + builder.setConnectionRequestTimeout(config.getConnectionRequestTimeout()); + builder.setSocketTimeout(config.getSocketTimeout()); + return builder.build(); + } + private QueryConfigurationsRequest firstPull(ConfigCenterConfig configCenterConfig, ConfigCenterClient configCenterClient, Environment environment, ConfigCenterAddressManager configCenterAddressManager) { @@ -169,16 +176,18 @@ private HttpTransport createHttpTransport(ConfigCenterAddressManager configCente private static RequestAuthHeaderProvider getRequestAuthHeaderProvider(List authHeaderProviders) { return signRequest -> { + String host = signRequest != null && signRequest.getEndpoint() != null ? signRequest.getEndpoint().getHost() : ""; Map headers = new HashMap<>(); - authHeaderProviders.forEach(provider -> headers.putAll(provider.authHeaders())); + authHeaderProviders.forEach(provider -> headers.putAll(provider.authHeaders(host))); return headers; }; } - private ConfigCenterAddressManager configCenterAddressManager(ConfigCenterConfig configCenterConfig) { + private ConfigCenterAddressManager configCenterAddressManager(ConfigCenterConfig configCenterConfig, Environment environment) { + String region = environment.getProperty("servicecomb.datacenter.region"); + String availableZone = environment.getProperty("servicecomb.datacenter.availableZone"); return new ConfigCenterAddressManager(configCenterConfig.getDomainName(), - configCenterConfig.getServerUri(), - EventManager.getEventBus()); + configCenterConfig.getServerUri(), EventManager.getEventBus(), region, availableZone); } @Override diff --git a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterAddressManagerTest.java b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterAddressManagerTest.java index 1642d11ff55..50d39bc19db 100644 --- a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterAddressManagerTest.java +++ b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterAddressManagerTest.java @@ -41,8 +41,8 @@ class ConfigCenterAddressManagerTest { public void addressManagerTest() throws NoSuchFieldException, IllegalAccessException { addresses.add("http://127.0.0.1:30103"); addresses.add("https://127.0.0.2:30103"); - addressManager1 = new ConfigCenterAddressManager("project", addresses, new EventBus()); - addressManager2 = new ConfigCenterAddressManager(null, addresses, new EventBus()); + addressManager1 = new ConfigCenterAddressManager("project", addresses, new EventBus(), "", ""); + addressManager2 = new ConfigCenterAddressManager(null, addresses, new EventBus(), "", ""); Field addressManagerField = addressManager1.getClass().getSuperclass().getDeclaredField("index"); addressManagerField.setAccessible(true); addressManagerField.set(addressManager1, 0); @@ -71,7 +71,7 @@ public void onRefreshEndpointEvent() { Map> zoneAndRegion = new HashMap<>(); zoneAndRegion.put("sameZone", addressAZ); zoneAndRegion.put("sameRegion", addressRG); - addressManager1 = new ConfigCenterAddressManager("project", addresses, new EventBus()); + addressManager1 = new ConfigCenterAddressManager("project", addresses, new EventBus(), "", ""); RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, "CseConfigCenter"); addressManager1.refreshEndpoint(event, "CseConfigCenter"); diff --git a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterConfigurationSourceImplTest.java b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterConfigurationSourceImplTest.java index f9424c9a2f2..3298d95bb19 100644 --- a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterConfigurationSourceImplTest.java +++ b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterConfigurationSourceImplTest.java @@ -36,7 +36,8 @@ void configAddressManagerTest() throws IllegalAccessException, NoSuchFieldExcept List addresses = new ArrayList<>(); addresses.add("http://127.0.0.1:30103"); addresses.add("http://127.0.0.2:30103"); - ConfigCenterAddressManager addressManager = new ConfigCenterAddressManager("test", addresses, EventManager.getEventBus()); + ConfigCenterAddressManager addressManager = new ConfigCenterAddressManager("test", addresses, + EventManager.getEventBus(), "", ""); Field addressManagerField = addressManager.getClass().getSuperclass().getDeclaredField("index"); addressManagerField.setAccessible(true); addressManagerField.set(addressManager, 0); @@ -47,7 +48,7 @@ void configAddressManagerTest() throws IllegalAccessException, NoSuchFieldExcept address = addressManager.address(); Assertions.assertEquals("http://127.0.0.1:30103/v3/test", address); - addressManager = new ConfigCenterAddressManager(null, addresses, EventManager.getEventBus()); + addressManager = new ConfigCenterAddressManager(null, addresses, EventManager.getEventBus(), "", ""); addressManagerField = addressManager.getClass().getSuperclass().getDeclaredField("index"); addressManagerField.setAccessible(true); addressManagerField.set(addressManager, 0); @@ -65,7 +66,8 @@ void onRefreshEndpointEventTest() { zoneAndRegion.put("sameZone", addressAZ); zoneAndRegion.put("sameRegion", new ArrayList<>()); RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion, "CseConfigCenter"); - ConfigCenterAddressManager addressManager = new ConfigCenterAddressManager("test", addresses, EventManager.getEventBus()); + ConfigCenterAddressManager addressManager = new ConfigCenterAddressManager("test", addresses, + EventManager.getEventBus(), "", ""); addressManager.onRefreshEndpointEvent(event); List availableAZ = addressManager.getAvailableZone(); diff --git a/dynamic-config/config-consul/pom.xml b/dynamic-config/config-consul/pom.xml new file mode 100644 index 00000000000..af890c0e6ec --- /dev/null +++ b/dynamic-config/config-consul/pom.xml @@ -0,0 +1,54 @@ + + + + + 4.0.0 + + org.apache.servicecomb + dynamic-config + 3.4.0-SNAPSHOT + + + config-consul + Java Chassis::Dynamic Config::Consul + + + + org.apache.servicecomb + foundation-common + + + org.apache.servicecomb + foundation-registry + + + org.apache.servicecomb + java-chassis-core + + + org.kiwiproject + consul-client + + + com.google.code.gson + gson + + + diff --git a/dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulConfig.java b/dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulConfig.java new file mode 100644 index 00000000000..57613037eb4 --- /dev/null +++ b/dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulConfig.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.config.consul; + +import org.springframework.core.env.Environment; + +public class ConsulConfig { + + public static final String CONSUL_CONFIG_PREFIX = "servicecomb.config.consul"; + + public static final String CONSUL_DEFAULT_ENVIRONMENT = "production"; + + public static final String PROPERTY_CONSUL_HOST = "servicecomb.config.consul.host"; + + public static final String PROPERTY_CONSUL_PORT = "servicecomb.config.consul.port"; + + public static final String PROPERTY_CONSUL_SCHEME = "servicecomb.config.consul.scheme"; + + public static final String PROPERTY_CONSUL_ACL_TOKEN = "servicecomb.config.consul.acl-token"; + + public static final String PROPERTY_CONSUL_WATCH_SECONDS = "servicecomb.config.consul.watch-seconds"; + + public static final String PROPERTY_INSTANCE_TAG = "servicecomb.config.consul.instance-tag"; + + public static final String PATH_ENVIRONMENT = "/servicecomb/config/environment/%s"; + + public static final String PATH_APPLICATION = "/servicecomb/config/application/%s/%s"; + + public static final String PATH_SERVICE = "/servicecomb/config/service/%s/%s/%s"; + + public static final String PATH_VERSION = "/servicecomb/config/version/%s/%s/%s/%s"; + + public static final String PATH_TAG = "/servicecomb/config/tag/%s/%s/%s/%s/%s"; + + private final Environment environment; + + public ConsulConfig(Environment environment) { + this.environment = environment; + } + + public String getConsulHost() { + return environment.getProperty(PROPERTY_CONSUL_HOST, String.class, "127.0.0.1"); + } + + public int getConsulPort() { + return environment.getProperty(PROPERTY_CONSUL_PORT, int.class, 8500); + } + + public String getConsulScheme() { + return environment.getProperty(PROPERTY_CONSUL_SCHEME); + } + + public String getConsulAclToken() { + return environment.getProperty(PROPERTY_CONSUL_ACL_TOKEN); + } + + public int getConsulWatchSeconds() { + return environment.getProperty(PROPERTY_CONSUL_WATCH_SECONDS, int.class, 8); + } + + public String getInstanceTag() { + return environment.getProperty(PROPERTY_INSTANCE_TAG); + } +} diff --git a/dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulConfigClient.java b/dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulConfigClient.java new file mode 100644 index 00000000000..ae18e11ff48 --- /dev/null +++ b/dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulConfigClient.java @@ -0,0 +1,305 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.config.consul; + +import org.apache.commons.lang3.StringUtils; +import org.apache.servicecomb.config.BootStrapProperties; +import org.jetbrains.annotations.NotNull; +import org.kiwiproject.consul.Consul; +import org.kiwiproject.consul.KeyValueClient; +import org.kiwiproject.consul.cache.KVCache; +import org.kiwiproject.consul.model.kv.Value; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; +import org.springframework.core.env.Environment; +import org.springframework.core.io.ByteArrayResource; + +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Properties; + +import static org.apache.servicecomb.config.consul.ConsulConfig.PATH_APPLICATION; +import static org.apache.servicecomb.config.consul.ConsulConfig.PATH_ENVIRONMENT; +import static org.apache.servicecomb.config.consul.ConsulConfig.PATH_SERVICE; +import static org.apache.servicecomb.config.consul.ConsulConfig.PATH_TAG; +import static org.apache.servicecomb.config.consul.ConsulConfig.PATH_VERSION; + +public class ConsulConfigClient { + private static final Logger LOGGER = LoggerFactory.getLogger(ConsulConfigClient.class); + + public class GetDataRunnable implements Runnable { + + private Map dataMap; + + private String path; + + public GetDataRunnable(String path, Map dataMap) { + this.dataMap = dataMap; + this.path = path; + } + + @Override + public void run() { + try { + if (path.equals("tagData")) { + tagData = dataMap; + } else if (path.equals("versionData")) { + versionData = dataMap; + } else if (path.equals("serviceData")) { + serviceData = dataMap; + } else if (path.equals("applicationData")) { + applicationData = dataMap; + } else { + environmentData = dataMap; + } + refreshConfigItems(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + private ConsulDynamicPropertiesSource.UpdateHandler updateHandler; + + private ConsulConfig consulConfig; + + private Environment environment; + + private final Object lock = new Object(); + + private Consul consulClient; + + private KeyValueClient kvClient; + + private ConsulConfigProperties consulConfigProperties; + + private Map environmentData = new HashMap<>(); + + private Map applicationData = new HashMap<>(); + + private Map serviceData = new HashMap<>(); + + private Map versionData = new HashMap<>(); + + private Map tagData = new HashMap<>(); + + private Map allLast = new HashMap<>(); + + public ConsulConfigClient(ConsulDynamicPropertiesSource.UpdateHandler updateHandler, Environment environment, ConsulConfigProperties consulConfigProperties, Consul consulClient) { + this.updateHandler = updateHandler; + this.consulConfig = new ConsulConfig(environment); + this.environment = environment; + this.consulConfigProperties = consulConfigProperties; + this.consulClient = consulClient; + this.kvClient = consulClient.keyValueClient(); + } + + public void refreshConsulConfig() { + String env = BootStrapProperties.readServiceEnvironment(environment); + if (StringUtils.isEmpty(env)) { + env = ConsulConfig.CONSUL_DEFAULT_ENVIRONMENT; + } + addEnvironmentConfig(env); + addApplicationConfig(env); + addServiceConfig(env); + addVersionConfig(env); + addTagConfig(env); + + refreshConfigItems(); + } + + private void addTagConfig(String env) { + if (StringUtils.isBlank(consulConfig.getInstanceTag())) { + return; + } + String path = String.format(PATH_TAG, env, + BootStrapProperties.readApplication(environment), + BootStrapProperties.readServiceName(environment), + BootStrapProperties.readServiceVersion(environment), + consulConfig.getInstanceTag()); + + this.tagData = parseData(path); + try (KVCache cache = KVCache.newCache(kvClient, path, consulConfig.getConsulWatchSeconds())) { + cache.addListener(newValues -> { + Optional newValue = newValues.values().stream() + .filter(value -> value.getKey().equals(path)) + .findAny(); + + newValue.ifPresent(value -> { + Optional decodedValue = newValue.get().getValueAsString(); + decodedValue.ifPresent(v -> new Thread(new GetDataRunnable("tagData", getValues(path))).start()); + }); + }); + cache.start(); + } + } + + private void addVersionConfig(String env) { + String path = String.format(PATH_VERSION, env, + BootStrapProperties.readApplication(environment), + BootStrapProperties.readServiceName(environment), + BootStrapProperties.readServiceVersion(environment)); + + this.versionData = parseData(path); + try (KVCache cache = KVCache.newCache(kvClient, path, consulConfig.getConsulWatchSeconds())) { + cache.addListener(newValues -> { + Optional newValue = newValues.values().stream() + .filter(value -> value.getKey().equals(path)) + .findAny(); + + newValue.ifPresent(value -> { + Optional decodedValue = newValue.get().getValueAsString(); + decodedValue.ifPresent(v -> new Thread(new GetDataRunnable("versionData", getValues(path))).start()); + }); + }); + cache.start(); + } + } + + private void addServiceConfig(String env) { + String path = String.format(PATH_SERVICE, env, + BootStrapProperties.readApplication(environment), + BootStrapProperties.readServiceName(environment)); + + this.serviceData = parseData(path); + try (KVCache cache = KVCache.newCache(kvClient, path, consulConfig.getConsulWatchSeconds())) { + cache.addListener(newValues -> { + Optional newValue = newValues.values().stream() + .filter(value -> value.getKey().equals(path)) + .findAny(); + + newValue.ifPresent(value -> { + Optional decodedValue = newValue.get().getValueAsString(); + decodedValue.ifPresent(v -> new Thread(new GetDataRunnable("serviceData", getValues(path))).start()); + }); + }); + cache.start(); + } + } + + private void addApplicationConfig(String env) { + String path = String.format(PATH_APPLICATION, env, BootStrapProperties.readApplication(environment)); + this.applicationData = parseData(path); + try (KVCache cache = KVCache.newCache(kvClient, path, consulConfig.getConsulWatchSeconds())) { + cache.addListener(newValues -> { + Optional newValue = newValues.values().stream() + .filter(value -> value.getKey().equals(path)) + .findAny(); + + newValue.ifPresent(value -> { + Optional decodedValue = newValue.get().getValueAsString(); + decodedValue.ifPresent(v -> new Thread(new GetDataRunnable("applicationData", getValues(path))).start()); + }); + }); + cache.start(); + } + } + + private void addEnvironmentConfig(String env) { + String path = String.format(PATH_ENVIRONMENT, env); + + this.environmentData = parseData(path); + try (KVCache cache = KVCache.newCache(kvClient, path, consulConfig.getConsulWatchSeconds())) { + cache.addListener(newValues -> { + Optional newValue = newValues.values().stream() + .filter(value -> value.getKey().equals(path)) + .findAny(); + + newValue.ifPresent(value -> { + Optional decodedValue = newValue.get().getValueAsString(); + decodedValue.ifPresent(v -> new Thread(new GetDataRunnable("environmentData", getValues(path))).start()); + }); + }); + cache.start(); + } + } + + public Map parseData(String path) { + try { + return getValues(path); + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + } + return new HashMap<>(); + } + + private Map getValues(String path) { + Map values = new HashMap<>(); + KeyValueClient keyValueClient = consulClient.keyValueClient(); + String decodedValue = keyValueClient.getValueAsString(path).orElseThrow(); + if (StringUtils.isBlank(decodedValue)) { + return values; + } + return getValues(path, decodedValue); + } + + private @NotNull Map getValues(String path, String decodedValue) { + Map values = new HashMap<>(); + if (path.endsWith(".yaml") || path.endsWith(".yml")) { + YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean(); + yamlFactory.setResources(new ByteArrayResource(decodedValue.getBytes(StandardCharsets.UTF_8))); + values.putAll(toMap(yamlFactory.getObject())); + } else if (path.endsWith(".properties")) { + Properties properties = new Properties(); + try { + properties.load(new StringReader(decodedValue)); + } catch (IOException e) { + LOGGER.error(e.getMessage(), e); + } + values.putAll(toMap(properties)); + } else { + values.put(path, decodedValue); + } + return values; + } + + private void refreshConfigItems() { + synchronized (lock) { + Map all = new HashMap<>(); + all.putAll(environmentData); + all.putAll(applicationData); + all.putAll(serviceData); + all.putAll(versionData); + all.putAll(tagData); + updateHandler.handle(all, allLast); + this.allLast = all; + } + } + + @SuppressWarnings("unchecked") + private Map toMap(Properties properties) { + if (properties == null) { + return Collections.emptyMap(); + } + Map result = new HashMap<>(); + Enumeration keys = (Enumeration) properties.propertyNames(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + Object value = properties.getProperty(key); + result.put(key, value); + } + return result; + } +} diff --git a/dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulConfigProperties.java b/dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulConfigProperties.java new file mode 100644 index 00000000000..fe3a278678a --- /dev/null +++ b/dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulConfigProperties.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.config.consul; + +public class ConsulConfigProperties { + + private String host = "localhost"; + + private Integer port = 8500; + + private String scheme = "http"; + + private String aclToken; + + private Integer watchSeconds = 8; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public String getScheme() { + return scheme; + } + + public void setScheme(String scheme) { + this.scheme = scheme; + } + + public String getAclToken() { + return aclToken; + } + + public void setAclToken(String aclToken) { + this.aclToken = aclToken; + } + + public Integer getWatchSeconds() { + return watchSeconds; + } + + public void setWatchSeconds(Integer watchSeconds) { + this.watchSeconds = watchSeconds; + } +} diff --git a/dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulDynamicPropertiesSource.java b/dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulDynamicPropertiesSource.java new file mode 100644 index 00000000000..9f0b3649249 --- /dev/null +++ b/dynamic-config/config-consul/src/main/java/org/apache/servicecomb/config/consul/ConsulDynamicPropertiesSource.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.config.consul; + +import com.google.common.net.HostAndPort; +import org.apache.commons.lang3.StringUtils; +import org.apache.servicecomb.config.ConfigurationChangedEvent; +import org.apache.servicecomb.config.DynamicPropertiesSource; +import org.apache.servicecomb.foundation.common.event.EventManager; +import org.kiwiproject.consul.Consul; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.env.Environment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertySource; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class ConsulDynamicPropertiesSource implements DynamicPropertiesSource { + private static final Logger LOGGER = LoggerFactory.getLogger(ConsulDynamicPropertiesSource.class); + + public static final String SOURCE_NAME = "consul"; + + private final Map valueCache = new ConcurrentHashMap<>(); + + private ConsulConfigClient consulConfigClient; + + public ConsulDynamicPropertiesSource() { + } + + private final UpdateHandler updateHandler = new UpdateHandler(); + public class UpdateHandler { + public void handle(Map current, Map last) { + ConfigurationChangedEvent event = ConfigurationChangedEvent.createIncremental(current, last); + LOGGER.info("Dynamic configuration changed: {}", event.getChanged()); + valueCache.putAll(event.getAdded()); + valueCache.putAll(event.getUpdated()); + event.getDeleted().forEach((k, v) -> valueCache.remove(k)); + EventManager.post(event); + } + } + + private ConsulConfigProperties consulConfigProperties(Environment environment) { + ConsulConfig consulConfig = new ConsulConfig(environment); + ConsulConfigProperties consulConfigProperties = new ConsulConfigProperties(); + consulConfigProperties.setHost(consulConfig.getConsulHost()); + consulConfigProperties.setPort(consulConfig.getConsulPort()); + consulConfigProperties.setScheme(consulConfig.getConsulScheme()); + consulConfigProperties.setAclToken(consulConfig.getConsulAclToken()); + consulConfigProperties.setWatchSeconds(consulConfig.getConsulWatchSeconds()); + return consulConfigProperties; + } + + private Consul consulClient(ConsulConfigProperties consulConfigProperties) { + Consul.Builder builder = Consul.builder().withHostAndPort(HostAndPort.fromParts(consulConfigProperties.getHost(), consulConfigProperties.getPort())); + if (StringUtils.isNotBlank(consulConfigProperties.getAclToken())) { + builder.withAclToken(consulConfigProperties.getAclToken()); + } + return builder.build(); + } + + private ConsulConfigClient consulConfigClient(Environment environment) { + ConsulConfigProperties consulConfigProperties = consulConfigProperties(environment); + Consul consulClient = consulClient(consulConfigProperties); + return new ConsulConfigClient(updateHandler, environment, consulConfigProperties, consulClient); + } + + @Override + public PropertySource create(Environment environment) { + try { + consulConfigClient = consulConfigClient(environment); + consulConfigClient.refreshConsulConfig(); + } catch (Exception e) { + throw new IllegalStateException("Set up consul config failed.", e); + } + return new MapPropertySource(SOURCE_NAME, valueCache); + } + + @Override + public int getOrder() { + return 0; + } +} diff --git a/dynamic-config/config-consul/src/main/resources/META-INF/services/org.apache.servicecomb.config.DynamicPropertiesSource b/dynamic-config/config-consul/src/main/resources/META-INF/services/org.apache.servicecomb.config.DynamicPropertiesSource new file mode 100644 index 00000000000..7b1c73e1195 --- /dev/null +++ b/dynamic-config/config-consul/src/main/resources/META-INF/services/org.apache.servicecomb.config.DynamicPropertiesSource @@ -0,0 +1,18 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +org.apache.servicecomb.config.consul.ConsulDynamicPropertiesSource diff --git a/dynamic-config/config-etcd/pom.xml b/dynamic-config/config-etcd/pom.xml index a1c35d9872f..8aa6b2cf963 100644 --- a/dynamic-config/config-etcd/pom.xml +++ b/dynamic-config/config-etcd/pom.xml @@ -22,7 +22,7 @@ dynamic-config org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 config-etcd diff --git a/dynamic-config/config-etcd/src/main/java/org/apache/servicecomb/config/etcd/EtcdClient.java b/dynamic-config/config-etcd/src/main/java/org/apache/servicecomb/config/etcd/EtcdClient.java index 80898ab513d..9a7743add07 100644 --- a/dynamic-config/config-etcd/src/main/java/org/apache/servicecomb/config/etcd/EtcdClient.java +++ b/dynamic-config/config-etcd/src/main/java/org/apache/servicecomb/config/etcd/EtcdClient.java @@ -47,7 +47,7 @@ public class EtcdClient { - public class GetDataRunable implements Runnable { + public class GetDataRunnable implements Runnable { private Map dataMap; @@ -55,7 +55,7 @@ public class GetDataRunable implements Runnable { private String path; - public GetDataRunable(Map dataMap, EtcdClient etcdClient, String path) { + public GetDataRunnable(Map dataMap, EtcdClient etcdClient, String path) { this.dataMap = dataMap; this.etcdClient = etcdClient; this.path = path; @@ -153,7 +153,7 @@ private void addTagConfig(String env) throws Exception { ByteSequence prefixByteSeq = ByteSequence.from(path, StandardCharsets.UTF_8); Watch watchClient = client.getWatchClient(); watchClient.watch(prefixByteSeq, WatchOption.builder().withPrefix(prefixByteSeq).build(), - resp -> new Thread(new GetDataRunable(tagData, this, path)).start()); + resp -> new Thread(new GetDataRunnable(tagData, this, path)).start()); this.tagData = parseData(path); } @@ -166,7 +166,7 @@ private void addVersionConfig(String env) throws Exception { ByteSequence prefixByteSeq = ByteSequence.from(path, StandardCharsets.UTF_8); Watch watchClient = client.getWatchClient(); watchClient.watch(prefixByteSeq, WatchOption.builder().withPrefix(prefixByteSeq).build(), - resp -> new Thread(new GetDataRunable(versionData, this, path)).start()); + resp -> new Thread(new GetDataRunnable(versionData, this, path)).start()); this.versionData = parseData(path); } @@ -178,7 +178,7 @@ private void addServiceConfig(String env) throws Exception { ByteSequence prefixByteSeq = ByteSequence.from(path, StandardCharsets.UTF_8); Watch watchClient = client.getWatchClient(); watchClient.watch(prefixByteSeq, WatchOption.builder().withPrefix(prefixByteSeq).build(), - resp -> new Thread(new GetDataRunable(serviceData, this, path)).start()); + resp -> new Thread(new GetDataRunnable(serviceData, this, path)).start()); this.serviceData = parseData(path); } @@ -188,7 +188,7 @@ private void addApplicationConfig(String env) throws Exception { ByteSequence prefixByteSeq = ByteSequence.from(path, StandardCharsets.UTF_8); Watch watchClient = client.getWatchClient(); watchClient.watch(prefixByteSeq, WatchOption.builder().withPrefix(prefixByteSeq).build(), - resp -> new Thread(new GetDataRunable(applicationData, this, path)).start()); + resp -> new Thread(new GetDataRunnable(applicationData, this, path)).start()); this.applicationData = parseData(path); } @@ -198,7 +198,7 @@ private void addEnvironmentConfig(String env) throws Exception { ByteSequence prefixByteSeq = ByteSequence.from(path, StandardCharsets.UTF_8); Watch watchClient = client.getWatchClient(); watchClient.watch(prefixByteSeq, WatchOption.builder().withPrefix(prefixByteSeq).build(), - resp -> new Thread(new GetDataRunable(environmentData, this, path)).start()); + resp -> new Thread(new GetDataRunnable(environmentData, this, path)).start()); this.environmentData = parseData(path); } diff --git a/dynamic-config/config-etcd/src/main/java/org/apache/servicecomb/config/etcd/EtcdConfig.java b/dynamic-config/config-etcd/src/main/java/org/apache/servicecomb/config/etcd/EtcdConfig.java index 57713eed069..ee04204c28a 100644 --- a/dynamic-config/config-etcd/src/main/java/org/apache/servicecomb/config/etcd/EtcdConfig.java +++ b/dynamic-config/config-etcd/src/main/java/org/apache/servicecomb/config/etcd/EtcdConfig.java @@ -21,17 +21,17 @@ public class EtcdConfig { public static final String ZOOKEEPER_DEFAULT_ENVIRONMENT = "production"; - public static final String PROPERTY_CONNECT_STRING = "servicecomb.config.etcd.connect-string"; + public static final String PROPERTY_CONNECT_STRING = "servicecomb.config.etcd.connectString"; - public static final String PROPERTY_SESSION_TIMEOUT = "servicecomb.config.etcd.session-timeout-millis"; + public static final String PROPERTY_SESSION_TIMEOUT = "servicecomb.config.etcd.sessionTimeoutMillis"; - public static final String PROPERTY_CONNECTION_TIMEOUT = "servicecomb.config.etcd.connection-timeout-mills"; + public static final String PROPERTY_CONNECTION_TIMEOUT = "servicecomb.config.etcd.connectionTimeoutMills"; - public static final String PROPERTY_AUTH_SCHEMA = "servicecomb.config.etcd.authentication-schema"; + public static final String PROPERTY_AUTH_SCHEMA = "servicecomb.config.etcd.authenticationSchema"; - public static final String PROPERTY_AUTH_INFO = "servicecomb.config.etcd.authentication-info"; + public static final String PROPERTY_AUTH_INFO = "servicecomb.config.etcd.authenticationInfo"; - public static final String PROPERTY_INSTANCE_TAG = "servicecomb.config.etcd.instance-tag"; + public static final String PROPERTY_INSTANCE_TAG = "servicecomb.config.etcd.instanceTag"; private final Environment environment; @@ -40,7 +40,7 @@ public EtcdConfig(Environment environment) { } public String getConnectString() { - return environment.getProperty(PROPERTY_CONNECT_STRING, "127.0.0.1:2181"); + return environment.getProperty(PROPERTY_CONNECT_STRING, "http://127.0.0.1:2379"); } public int getSessionTimeoutMillis() { diff --git a/dynamic-config/config-kie/pom.xml b/dynamic-config/config-kie/pom.xml index b0f2226f552..4bf61b5801f 100644 --- a/dynamic-config/config-kie/pom.xml +++ b/dynamic-config/config-kie/pom.xml @@ -23,7 +23,7 @@ dynamic-config org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfig.java b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfig.java index 564b5c8ad17..79e40786f8f 100644 --- a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfig.java +++ b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfig.java @@ -66,6 +66,12 @@ public class KieConfig { private static final String CUSTOM_LABEL_VALUE_DEFAULT = ""; + private static final String CLIENT_CONNECT_TIMEOUT = "servicecomb.kie.client.timeout.connect"; + + private static final String CLIENT_REQUEST_TIMEOUT = "servicecomb.kie.client.timeout.request"; + + private static final String CLIENT_SOCKET_TIMEOUT = "servicecomb.kie.client.timeout.socket"; + private final Environment environment; public KieConfig(Environment environment) { @@ -148,4 +154,16 @@ public String getProxyUsername() { public String getProxyPasswd() { return environment.getProperty(VertxConst.PROXY_PASSWD); } + + public int getConnectTimeout() { + return environment.getProperty(CLIENT_CONNECT_TIMEOUT, int.class, 5000); + } + + public int getConnectionRequestTimeout() { + return environment.getProperty(CLIENT_REQUEST_TIMEOUT, int.class, 5000); + } + + public int getSocketTimeout() { + return environment.getProperty(CLIENT_SOCKET_TIMEOUT, int.class, 5000); + } } diff --git a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieDynamicPropertiesSource.java b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieDynamicPropertiesSource.java index 716579692bd..6683b84fb09 100644 --- a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieDynamicPropertiesSource.java +++ b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieDynamicPropertiesSource.java @@ -26,6 +26,7 @@ import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.config.RequestConfig.Builder; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.servicecomb.config.BootStrapProperties; @@ -70,9 +71,9 @@ public KieDynamicPropertiesSource() { private void init(Environment environment) { KieConfig kieConfig = new KieConfig(environment); configConverter = new ConfigConverter(kieConfig.getFileSources()); - KieAddressManager kieAddressManager = configKieAddressManager(kieConfig); + KieAddressManager kieAddressManager = configKieAddressManager(kieConfig, environment); - RequestConfig.Builder requestBuilder = HttpTransportFactory.defaultRequestConfig(); + RequestConfig.Builder requestBuilder = buildRequestConfigBuilder(kieConfig); if (kieConfig.enableLongPolling() && kieConfig.getPollingWaitTime() >= 0) { requestBuilder.setConnectionRequestTimeout(kieConfig.getPollingWaitTime() * 2 * 1000); @@ -90,6 +91,14 @@ private void init(Environment environment) { data.putAll(configConverter.getCurrentData()); } + private Builder buildRequestConfigBuilder(KieConfig kieConfig) { + Builder builder = HttpTransportFactory.defaultRequestConfig(); + builder.setConnectTimeout(kieConfig.getConnectTimeout()); + builder.setConnectionRequestTimeout(kieConfig.getConnectionRequestTimeout()); + builder.setSocketTimeout(kieConfig.getSocketTimeout()); + return builder; + } + @Subscribe public void onConfigurationChangedEvent(KieConfigurationChangedEvent event) { LOGGER.info("Dynamic configuration changed: {}", event.getChanged()); @@ -152,15 +161,18 @@ private HttpTransport createHttpTransport(KieAddressManager kieAddressManager, private static RequestAuthHeaderProvider getRequestAuthHeaderProvider(List authHeaderProviders) { return signRequest -> { + String host = signRequest != null && signRequest.getEndpoint() != null ? signRequest.getEndpoint().getHost() : ""; Map headers = new HashMap<>(); - authHeaderProviders.forEach(provider -> headers.putAll(provider.authHeaders())); + authHeaderProviders.forEach(provider -> headers.putAll(provider.authHeaders(host))); return headers; }; } - private KieAddressManager configKieAddressManager(KieConfig kieConfig) { + private KieAddressManager configKieAddressManager(KieConfig kieConfig, Environment environment) { + String region = environment.getProperty("servicecomb.datacenter.region"); + String availableZone = environment.getProperty("servicecomb.datacenter.availableZone"); return new KieAddressManager( - Arrays.asList(kieConfig.getServerUri().split(",")), EventManager.getEventBus()); + Arrays.asList(kieConfig.getServerUri().split(",")), EventManager.getEventBus(), region, availableZone); } @Override diff --git a/dynamic-config/config-nacos/pom.xml b/dynamic-config/config-nacos/pom.xml index b378d27ce45..395603f9fd6 100644 --- a/dynamic-config/config-nacos/pom.xml +++ b/dynamic-config/config-nacos/pom.xml @@ -22,7 +22,7 @@ dynamic-config org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 config-nacos diff --git a/dynamic-config/config-zookeeper/pom.xml b/dynamic-config/config-zookeeper/pom.xml index 767d3a4649f..35fabec9591 100644 --- a/dynamic-config/config-zookeeper/pom.xml +++ b/dynamic-config/config-zookeeper/pom.xml @@ -22,7 +22,7 @@ dynamic-config org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 config-zookeeper diff --git a/dynamic-config/pom.xml b/dynamic-config/pom.xml index 540381370f9..d5777cd654c 100644 --- a/dynamic-config/pom.xml +++ b/dynamic-config/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default 4.0.0 @@ -38,6 +38,7 @@ config-kie config-zookeeper config-etcd + config-consul diff --git a/edge/edge-core/pom.xml b/edge/edge-core/pom.xml index e270e5abf6d..0a75f8e33c6 100644 --- a/edge/edge-core/pom.xml +++ b/edge/edge-core/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb edge - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT edge-core Java Chassis::Edge::Core diff --git a/edge/pom.xml b/edge/pom.xml index d75f7db7d5a..e11f4e088b6 100644 --- a/edge/pom.xml +++ b/edge/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default edge diff --git a/foundations/foundation-common/pom.xml b/foundations/foundation-common/pom.xml index 3e07a454296..2f5a18878b4 100644 --- a/foundations/foundation-common/pom.xml +++ b/foundations/foundation-common/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT foundations foundation-common diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/cache/VersionedCache.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/cache/VersionedCache.java index 6580174861e..b30e13862b4 100644 --- a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/cache/VersionedCache.java +++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/cache/VersionedCache.java @@ -30,7 +30,7 @@ interface IsEmpty { boolean isEmpty(); } - protected int cacheVersion; + protected volatile int cacheVersion; // an optional name protected String name; diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/net/IpPort.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/net/IpPort.java index d8515eea13a..66aae3ebca7 100644 --- a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/net/IpPort.java +++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/net/IpPort.java @@ -22,9 +22,9 @@ import com.google.common.base.Objects; public class IpPort { - private String hostOrIp; + private volatile String hostOrIp; - private int port; + private volatile int port; private volatile InetSocketAddress socketAddress; diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/GenericsUtils.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/GenericsUtils.java index 0429b82da70..d872236082e 100644 --- a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/GenericsUtils.java +++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/GenericsUtils.java @@ -24,14 +24,14 @@ public final class GenericsUtils { /** * check if XXX.class is generic type. see TestGenericsUtils for details meaning. * This method is provided for API compatibility for RestTemplate. Following code: - * - * + *

+ *{@code * List>> response = consumers.getSCBRestTemplate() * postForObject("/testListObjectParam", request, List.class); - * + * } * * should work for versions of 1.*. This is because java-chassis can read type info from swaggers. - * + *

* Start from 2.x, the best practise to write this code is to use ParameterizedTypeReference provided by RestTemplate * exchange method. */ diff --git a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/event/TestEventManager.java b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/event/TestEventManager.java index 184431d8dd7..736a933159b 100644 --- a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/event/TestEventManager.java +++ b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/event/TestEventManager.java @@ -48,7 +48,7 @@ public void normalListener() { test(this); Assertions.assertTrue(collector.getEvents().isEmpty()); // ensure no warning logs - collector.teardown(); + collector.tearDown(); } @Test @@ -72,7 +72,7 @@ void onInt(Integer obj) { Assertions.assertTrue(true); } - collector.teardown(); + collector.tearDown(); } @Test @@ -98,7 +98,7 @@ public void onInt(Integer obj) { // ensure logs: "LOGGER.warn("Failed to create lambda for method: {}, fallback to reflect.", method, throwable);" Assertions.assertFalse(collector.getEvents().isEmpty()); - collector.teardown(); + collector.tearDown(); } @Subscribe diff --git a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestJvmUtils.java b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestJvmUtils.java index 89da7bd52b3..10054efe4e8 100644 --- a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestJvmUtils.java +++ b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestJvmUtils.java @@ -56,7 +56,7 @@ public void findMainClass_invalid() { Assertions.assertNull(JvmUtils.findMainClass()); Assertions.assertEquals("\"invalidCls\" is not a valid class.", logCollector.getEvents().get(0).getMessage()); - logCollector.teardown(); + logCollector.tearDown(); } @Test diff --git a/foundations/foundation-config/pom.xml b/foundations/foundation-config/pom.xml index 14629e95a32..12c4a54c5be 100644 --- a/foundations/foundation-config/pom.xml +++ b/foundations/foundation-config/pom.xml @@ -21,7 +21,7 @@ foundations org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/DynamicPropertiesImpl.java b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/DynamicPropertiesImpl.java index 84f623d74d9..323e84d80aa 100644 --- a/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/DynamicPropertiesImpl.java +++ b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/DynamicPropertiesImpl.java @@ -17,11 +17,11 @@ package org.apache.servicecomb.config; -import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; import java.util.function.DoubleConsumer; import java.util.function.IntConsumer; @@ -44,17 +44,17 @@ private static class Holder { } } - private final Map, String>>> stringCallbacks = new HashMap<>(); + private final Map, String>>> stringCallbacks = new ConcurrentHashMap<>(); - private final Map>> intCallbacks = new HashMap<>(); + private final Map>> intCallbacks = new ConcurrentHashMap<>(); - private final Map>> longCallbacks = new HashMap<>(); + private final Map>> longCallbacks = new ConcurrentHashMap<>(); - private final Map>> floatCallbacks = new HashMap<>(); + private final Map>> floatCallbacks = new ConcurrentHashMap<>(); - private final Map>> doubleCallbacks = new HashMap<>(); + private final Map>> doubleCallbacks = new ConcurrentHashMap<>(); - private final Map, Boolean>>> booleanCallbacks = new HashMap<>(); + private final Map, Boolean>>> booleanCallbacks = new ConcurrentHashMap<>(); private final Environment environment; diff --git a/foundations/foundation-metrics/pom.xml b/foundations/foundation-metrics/pom.xml index cce230c8948..d893011c4d4 100644 --- a/foundations/foundation-metrics/pom.xml +++ b/foundations/foundation-metrics/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb foundations - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT foundation-metrics Java Chassis::Foundations::Metrics diff --git a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementGroupConfig.java b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementGroupConfig.java index b4637386720..60d77b4c75a 100644 --- a/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementGroupConfig.java +++ b/foundations/foundation-metrics/src/test/java/org/apache/servicecomb/foundation/metrics/publish/spectator/TestMeasurementGroupConfig.java @@ -53,7 +53,7 @@ public void addGroup() { config.addGroup("id1", "tag1.1", "tag1.2"); config.addGroup("id2", "tag2.1", "tag2.2"); - MatcherAssert.assertThat(groups.keySet(), Matchers.contains("id2", "id1")); + MatcherAssert.assertThat(groups.keySet(), Matchers.containsInAnyOrder("id2", "id1")); MatcherAssert.assertThat(groups.get("id1").stream().map(TagFinder::getTagKey).toArray(), Matchers.arrayContaining("tag1.1", "tag1.2")); MatcherAssert.assertThat(groups.get("id2").stream().map(TagFinder::getTagKey).toArray(), Matchers.arrayContaining("tag2.1", "tag2.2")); } diff --git a/foundations/foundation-protobuf/pom.xml b/foundations/foundation-protobuf/pom.xml index e58e0ad8242..cb8662c7bfb 100644 --- a/foundations/foundation-protobuf/pom.xml +++ b/foundations/foundation-protobuf/pom.xml @@ -21,7 +21,7 @@ foundations org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java index 331c6b63284..5d583954ca0 100644 --- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java +++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java @@ -166,14 +166,14 @@ public FieldMapEx> createMapFields(Message message, Map types, String perameterName) { + private JavaType getParameterType(Map types, String parameterName) { - if (types.get(perameterName) != null) { - return TypeFactory.defaultInstance().constructType(types.get(perameterName)); + if (types.get(parameterName) != null) { + return TypeFactory.defaultInstance().constructType(types.get(parameterName)); } throw new IllegalArgumentException( - String.format("not found type info for parameter name [%s]", perameterName)); + String.format("not found type info for parameter name [%s]", parameterName)); } public FieldSchema createSchemaField(Field protoField, PropertyDescriptor propertyDescriptor) { diff --git a/foundations/foundation-registry/pom.xml b/foundations/foundation-registry/pom.xml index 7e78cd937a4..d4cca8111c4 100644 --- a/foundations/foundation-registry/pom.xml +++ b/foundations/foundation-registry/pom.xml @@ -21,7 +21,7 @@ foundations org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java index 2cbe83a2465..edcd3b3caef 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java @@ -183,7 +183,7 @@ private VersionedCache calcAvailableInstance(String application, String serviceN continue; } if (instance.getHistoryStatus() == HistoryStatus.HISTORY - && instance.getMicroserviceInstanceStatus() == MicroserviceInstanceStatus.UP + && instance.getStatus() == MicroserviceInstanceStatus.UP && instance.getPingStatus() == PingStatus.OK && instance.getIsolationStatus() == IsolationStatus.NORMAL) { result.add(instance); diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/RegistrationManager.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/RegistrationManager.java index 0639d00f401..9c135d380c8 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/RegistrationManager.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/RegistrationManager.java @@ -24,6 +24,7 @@ import java.util.stream.Collectors; import org.apache.servicecomb.foundation.common.utils.LambdaUtils; +import org.apache.servicecomb.foundation.common.utils.SPIEnabled; import org.apache.servicecomb.registry.api.LifeCycle; import org.apache.servicecomb.registry.api.MicroserviceInstanceStatus; import org.apache.servicecomb.registry.api.Registration; @@ -40,7 +41,7 @@ public RegistrationManager(List> re this.registrationList = Collections.emptyList(); return; } - this.registrationList = registrationList; + this.registrationList = registrationList.stream().filter(SPIEnabled::enabled).collect(Collectors.toList()); } /** diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/MicroserviceInstance.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/MicroserviceInstance.java index 0dd6d0237c0..c5c872beefd 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/MicroserviceInstance.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/MicroserviceInstance.java @@ -93,4 +93,10 @@ public interface MicroserviceInstance { default String getServiceId() { return ""; } + + /** + * Service status(Required): status of this microservice. + * + */ + MicroserviceInstanceStatus getStatus(); } diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/Registration.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/Registration.java index c5529619f56..014da5f147b 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/Registration.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/Registration.java @@ -22,42 +22,42 @@ /** - * This is the core service registration interface.
+ * This is the core service registration interface. */ public interface Registration extends SPIEnabled, SPIOrder, LifeCycle { String name(); /** - * get MicroserviceInstance
- * + * get MicroserviceInstance + *

* Life Cycle:This method is called anytime after run. */ R getMicroserviceInstance(); /** - * update MicroserviceInstance status
- * + * update MicroserviceInstance status + *

* Life Cycle:This method is called anytime after run. */ boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status); /** - * adding schemas to Microservice
- * + * adding schemas to Microservice + *

* Life Cycle:This method is called after init and before run. */ void addSchema(String schemaId, String content); /** - * adding endpoints to MicroserviceInstance
- * + * adding endpoints to MicroserviceInstance + *

* Life Cycle:This method is called after init and before run. */ void addEndpoint(String endpoint); /** - * adding property to MicroserviceInstance
- * + * adding property to MicroserviceInstance + *

* Life Cycle:This method is called after init and before run. */ void addProperty(String key, String value); diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/RegistrationInstance.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/RegistrationInstance.java index afe2bc7a878..a7d7cafda88 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/RegistrationInstance.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/RegistrationInstance.java @@ -20,15 +20,4 @@ * Microserivce instance registration object. */ public interface RegistrationInstance extends MicroserviceInstance { - /** - * Initial status when registering(Optional). This method is - * implementation specific and may be not used. - */ - MicroserviceInstanceStatus getInitialStatus(); - - /** - * Ready status when microservice instance is ready for service(Optional).This method is - * implementation specific and may be not used. - */ - MicroserviceInstanceStatus getReadyStatus(); } diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/AbstractDiscoveryFilter.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/AbstractDiscoveryFilter.java index 5883ec51bf3..f274799c30e 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/AbstractDiscoveryFilter.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/AbstractDiscoveryFilter.java @@ -19,19 +19,21 @@ import java.util.ArrayList; +import org.apache.servicecomb.config.DynamicProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.env.Environment; public abstract class AbstractDiscoveryFilter implements DiscoveryFilter { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractDiscoveryFilter.class); - protected Environment environment; + protected Boolean enabled; + + protected DynamicProperties dynamicProperties; @Autowired - public void setEnvironment(Environment environment) { - this.environment = environment; + public void setDynamicProperties(DynamicProperties dynamicProperties) { + this.dynamicProperties = dynamicProperties; } @Override diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/DiscoveryTreeNode.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/DiscoveryTreeNode.java index 3dda15f6c4b..e0f7c828c10 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/DiscoveryTreeNode.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/DiscoveryTreeNode.java @@ -25,7 +25,7 @@ public class DiscoveryTreeNode extends VersionedCache { private volatile boolean childrenInited; - private int level; + private volatile int level; protected Map attributes = new ConcurrentHashMapEx<>(); diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/InstanceStatusDiscoveryFilter.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/InstanceStatusDiscoveryFilter.java index ef60b4a3eff..e7a4029bdeb 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/InstanceStatusDiscoveryFilter.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/InstanceStatusDiscoveryFilter.java @@ -32,6 +32,8 @@ public class InstanceStatusDiscoveryFilter extends AbstractGroupDiscoveryFilter public static final String GROUP_SIZE = "status_group_size"; + public static final String SERVICECOMB_LOADBALANCE_FILTER_STATUS_ENABLED = "servicecomb.loadbalance.filter.status.enabled"; + @Override public int getOrder() { return -10000; @@ -39,7 +41,13 @@ public int getOrder() { @Override public boolean enabled() { - return environment.getProperty("servicecomb.loadbalance.filter.status.enabled", Boolean.class, true); + + if (enabled == null) { + enabled = dynamicProperties.getBooleanProperty(SERVICECOMB_LOADBALANCE_FILTER_STATUS_ENABLED, + value -> enabled = value, + true); + } + return enabled; } @Override @@ -69,21 +77,21 @@ public void init(DiscoveryContext context, DiscoveryTreeNode parent) { for (StatefulDiscoveryInstance instance : instances) { if (HistoryStatus.CURRENT == instance.getHistoryStatus() && - MicroserviceInstanceStatus.UP == instance.getMicroserviceInstanceStatus() && + MicroserviceInstanceStatus.UP == instance.getStatus() && PingStatus.OK == instance.getPingStatus() && IsolationStatus.NORMAL == instance.getIsolationStatus()) { level0.add(instance); continue; } if (HistoryStatus.CURRENT == instance.getHistoryStatus() && - MicroserviceInstanceStatus.UP == instance.getMicroserviceInstanceStatus() && + MicroserviceInstanceStatus.UP == instance.getStatus() && PingStatus.UNKNOWN == instance.getPingStatus() && IsolationStatus.NORMAL == instance.getIsolationStatus()) { level1.add(instance); continue; } if (HistoryStatus.HISTORY == instance.getHistoryStatus() && - MicroserviceInstanceStatus.UP == instance.getMicroserviceInstanceStatus() && + MicroserviceInstanceStatus.UP == instance.getStatus() && PingStatus.OK == instance.getPingStatus() && IsolationStatus.NORMAL == instance.getIsolationStatus()) { level2.add(instance); diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/StatefulDiscoveryInstance.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/StatefulDiscoveryInstance.java index f06ea936d20..394b2b03ccc 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/StatefulDiscoveryInstance.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/StatefulDiscoveryInstance.java @@ -46,8 +46,6 @@ public enum HistoryStatus { private final DiscoveryInstance discoveryInstance; - private MicroserviceInstanceStatus microserviceInstanceStatus = MicroserviceInstanceStatus.UP; - private IsolationStatus isolationStatus = IsolationStatus.NORMAL; private long isolatedTime; @@ -64,15 +62,6 @@ public StatefulDiscoveryInstance(DiscoveryInstance discoveryInstance) { this.discoveryInstance = discoveryInstance; } - public MicroserviceInstanceStatus getMicroserviceInstanceStatus() { - return microserviceInstanceStatus; - } - - public void setMicroserviceInstanceStatus( - MicroserviceInstanceStatus microserviceInstanceStatus) { - this.microserviceInstanceStatus = microserviceInstanceStatus; - } - public IsolationStatus getIsolationStatus() { return isolationStatus; } diff --git a/foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestDiscoveryTree.java b/foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestDiscoveryTree.java index a30b892f8b4..d726d1b59c0 100644 --- a/foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestDiscoveryTree.java +++ b/foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestDiscoveryTree.java @@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.servicecomb.config.DynamicProperties; import org.apache.servicecomb.foundation.common.cache.VersionedCache; import org.apache.servicecomb.foundation.common.exceptions.ServiceCombException; import org.apache.servicecomb.registry.DiscoveryManager; @@ -32,7 +33,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import org.springframework.core.env.Environment; public class TestDiscoveryTree { DiscoveryContext context = new DiscoveryContext(); @@ -238,11 +238,12 @@ public void test_one_service_concurrent_correct() throws Exception { DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager); DiscoveryContext discoveryContext = new DiscoveryContext(); InstanceStatusDiscoveryFilter filter = new InstanceStatusDiscoveryFilter(); - Environment environment = Mockito.mock(Environment.class); - Mockito.when(environment - .getProperty("servicecomb.loadbalance.filter.status.enabled", Boolean.class, true)) + DynamicProperties dynamicProperties = Mockito.mock(DynamicProperties.class); + Mockito.when(dynamicProperties.getBooleanProperty(Mockito.eq("servicecomb.loadbalance.filter.status.enabled"), + Mockito.any(), + Mockito.eq(true))) .thenReturn(true); - filter.setEnvironment(environment); + filter.setDynamicProperties(dynamicProperties); discoveryTree.setDiscoveryFilters(List.of(filter)); StatefulDiscoveryInstance instance1 = Mockito.mock(StatefulDiscoveryInstance.class); diff --git a/foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestInstanceStatusDiscoveryFilter.java b/foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestInstanceStatusDiscoveryFilter.java index eeecc420096..8e7307098b9 100644 --- a/foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestInstanceStatusDiscoveryFilter.java +++ b/foundations/foundation-registry/src/test/java/org/apache/servicecomb/registry/discovery/TestInstanceStatusDiscoveryFilter.java @@ -36,22 +36,22 @@ public void test_all_group_correct_init() { List instances = new ArrayList<>(); StatefulDiscoveryInstance instance1 = Mockito.mock(StatefulDiscoveryInstance.class); Mockito.when(instance1.getHistoryStatus()).thenReturn(HistoryStatus.CURRENT); - Mockito.when(instance1.getMicroserviceInstanceStatus()).thenReturn(MicroserviceInstanceStatus.UP); + Mockito.when(instance1.getStatus()).thenReturn(MicroserviceInstanceStatus.UP); Mockito.when(instance1.getPingStatus()).thenReturn(PingStatus.OK); Mockito.when(instance1.getIsolationStatus()).thenReturn(IsolationStatus.NORMAL); StatefulDiscoveryInstance instance2 = Mockito.mock(StatefulDiscoveryInstance.class); Mockito.when(instance2.getHistoryStatus()).thenReturn(HistoryStatus.CURRENT); - Mockito.when(instance2.getMicroserviceInstanceStatus()).thenReturn(MicroserviceInstanceStatus.UP); + Mockito.when(instance2.getStatus()).thenReturn(MicroserviceInstanceStatus.UP); Mockito.when(instance2.getPingStatus()).thenReturn(PingStatus.UNKNOWN); Mockito.when(instance2.getIsolationStatus()).thenReturn(IsolationStatus.NORMAL); StatefulDiscoveryInstance instance3 = Mockito.mock(StatefulDiscoveryInstance.class); Mockito.when(instance3.getHistoryStatus()).thenReturn(HistoryStatus.HISTORY); - Mockito.when(instance3.getMicroserviceInstanceStatus()).thenReturn(MicroserviceInstanceStatus.UP); + Mockito.when(instance3.getStatus()).thenReturn(MicroserviceInstanceStatus.UP); Mockito.when(instance3.getPingStatus()).thenReturn(PingStatus.OK); Mockito.when(instance3.getIsolationStatus()).thenReturn(IsolationStatus.NORMAL); StatefulDiscoveryInstance instance4 = Mockito.mock(StatefulDiscoveryInstance.class); Mockito.when(instance4.getHistoryStatus()).thenReturn(HistoryStatus.CURRENT); - Mockito.when(instance4.getMicroserviceInstanceStatus()).thenReturn(MicroserviceInstanceStatus.UP); + Mockito.when(instance4.getStatus()).thenReturn(MicroserviceInstanceStatus.UP); Mockito.when(instance4.getPingStatus()).thenReturn(PingStatus.FAIL); Mockito.when(instance4.getIsolationStatus()).thenReturn(IsolationStatus.NORMAL); instances.addAll(Arrays.asList(instance1, instance2, instance3, instance4)); diff --git a/foundations/foundation-registry/src/test/resources/log4j2.xml b/foundations/foundation-registry/src/test/resources/log4j2.xml index 8cee07220ec..3125ebd11e4 100644 --- a/foundations/foundation-registry/src/test/resources/log4j2.xml +++ b/foundations/foundation-registry/src/test/resources/log4j2.xml @@ -16,14 +16,14 @@ under the License. --> - - - - - - - - - - + + + + + + + + + + diff --git a/foundations/foundation-spi/pom.xml b/foundations/foundation-spi/pom.xml index 0f58fc313ac..aa38214b3ee 100644 --- a/foundations/foundation-spi/pom.xml +++ b/foundations/foundation-spi/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb foundations - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT foundation-spi Java Chassis::Foundations::SSL diff --git a/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java index 313c19ee5ba..0e036e21a58 100644 --- a/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java +++ b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java @@ -21,11 +21,21 @@ import java.util.Map; public interface AuthHeaderProvider { - default Map authHeaders() { + /** + * Obtain RBAC authentication request header, host is the key of cache + * + * @param host engine address ip + * @return auth headers + */ + default Map authHeaders(String host) { return new HashMap<>(0); } default Map getSignAuthHeaders(SignRequest request) { - return authHeaders(); + String host = ""; + if (request != null && request.getEndpoint() != null) { + host = request.getEndpoint().getHost(); + } + return authHeaders(host); } } diff --git a/foundations/foundation-ssl/pom.xml b/foundations/foundation-ssl/pom.xml index 2e2225ad3a8..3cf7cdcb485 100644 --- a/foundations/foundation-ssl/pom.xml +++ b/foundations/foundation-ssl/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb foundations - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT foundation-ssl Java Chassis::Foundations::SSL diff --git a/foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/KeyStoreUtilTest.java b/foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/KeyStoreUtilTest.java index f7d046f6562..54955139087 100644 --- a/foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/KeyStoreUtilTest.java +++ b/foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/KeyStoreUtilTest.java @@ -26,13 +26,12 @@ import java.security.cert.CertificateFactory; import java.util.Collection; -import org.apache.commons.lang3.SystemUtils; import org.junit.Test; import org.junit.jupiter.api.Assertions; -import org.mockito.Mockito; import mockit.Mock; import mockit.MockUp; +import org.mockito.Mockito; public class KeyStoreUtilTest { final String strFilePath = Thread.currentThread().getContextClassLoader().getResource("").getPath(); @@ -78,14 +77,9 @@ public void testCreateKeyManagersException() { try { KeyStoreUtil.createKeyManagers(keystore, storeKeyValue); } catch (IllegalArgumentException e) { - if (SystemUtils.JAVA_SPECIFICATION_VERSION.startsWith("17")) { Assertions.assertEquals("Bad key store.Get Key failed:" + " Cannot read the array length because \"password\" is null", e.getMessage()); - } else { - Assertions.assertEquals("Bad key store.Get Key failed: null", - e.getMessage()); - } } } diff --git a/foundations/foundation-test-scaffolding/pom.xml b/foundations/foundation-test-scaffolding/pom.xml index b5c048ed5d7..f3feba62148 100644 --- a/foundations/foundation-test-scaffolding/pom.xml +++ b/foundations/foundation-test-scaffolding/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb foundations - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT foundation-test-scaffolding Java Chassis::Foundations::Test Scaffolding diff --git a/foundations/foundation-test-scaffolding/src/main/java/io/vertx/core/impl/SyncContext.java b/foundations/foundation-test-scaffolding/src/main/java/io/vertx/core/impl/SyncContext.java deleted file mode 100644 index ec50fc1b6c1..00000000000 --- a/foundations/foundation-test-scaffolding/src/main/java/io/vertx/core/impl/SyncContext.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.vertx.core.impl; - -import java.io.Serial; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; - -import io.netty.channel.EventLoop; -import io.vertx.codegen.annotations.Nullable; -import io.vertx.core.AsyncResult; -import io.vertx.core.Context; -import io.vertx.core.Future; -import io.vertx.core.Handler; -import io.vertx.core.Promise; -import io.vertx.core.ThreadingModel; -import io.vertx.core.json.JsonObject; -import io.vertx.core.spi.tracing.VertxTracer; - -/** - * This class is created to make vertx unit test easier - */ -@SuppressWarnings({"rawtypes"}) -public class SyncContext extends ContextBase implements ContextInternal { - @Serial - private static final long serialVersionUID = -6209656149925076980L; - - protected VertxInternal owner; - - protected Executor executor = Executors.newSingleThreadExecutor(); - - public SyncContext() { - this(0); - } - - public SyncContext(int localsLength) { - super(localsLength); - } - - @Override - public VertxInternal owner() { - return owner; - } - - @Override - public Context exceptionHandler(@Nullable Handler handler) { - return null; - } - - @Override - public @Nullable Handler exceptionHandler() { - return null; - } - - @Override - public boolean inThread() { - return false; - } - - @Override - public void emit(T t, Handler handler) { - - } - - @Override - public void execute(Runnable runnable) { - - } - - @Override - public void execute(T t, Handler handler) { - - } - - @Override - public Future close() { - return Future.succeededFuture(); - } - - @Override - public void reportException(Throwable throwable) { - - } - - @Override - public ConcurrentMap contextData() { - return null; - } - - @Override - public ClassLoader classLoader() { - return null; - } - - @Override - public WorkerPool workerPool() { - return null; - } - - @Override - public VertxTracer tracer() { - return null; - } - - @Override - public ContextInternal duplicate() { - return null; - } - - @Override - public CloseFuture closeFuture() { - return null; - } - - public void setOwner(VertxInternal owner) { - this.owner = owner; - } - - - public static void syncExecuteBlocking(Handler> blockingCodeHandler, - Handler> asyncResultHandler) { - Promise res = Promise.promise(); - - try { - blockingCodeHandler.handle(res); - } catch (Throwable e) { - res.fail(e); - return; - } - - res.future().onComplete(asyncResultHandler); - } - - private static Future syncExecuteBlocking(Handler> blockingCodeHandler) { - Promise res = Promise.promise(); - - try { - blockingCodeHandler.handle(res); - } catch (Throwable e) { - res.fail(e); - return res.future(); - } - - return res.future(); - } - - @Override - public Future executeBlockingInternal(Handler> action) { - return syncExecuteBlocking(action); - } - - @Override - public Future executeBlockingInternal(Callable callable) { - return null; - } - - @Override - public Future executeBlockingInternal(Handler> handler, boolean b) { - return null; - } - - @Override - public Future executeBlockingInternal(Callable callable, boolean b) { - return null; - } - - @Override - public Deployment getDeployment() { - return null; - } - - @Override - public Executor executor() { - return executor; - } - - @Override - public EventLoop nettyEventLoop() { - return null; - } - - @Override - @Deprecated - public Future executeBlocking(Handler> handler, TaskQueue taskQueue) { - return null; - } - - @Override - public Future executeBlocking(Callable callable, TaskQueue taskQueue) { - return null; - } - - @Override - @Deprecated - public void executeBlocking(Handler> blockingCodeHandler, boolean ordered, - Handler> asyncResultHandler) { - syncExecuteBlocking(blockingCodeHandler, asyncResultHandler); - } - - @Override - public Future<@Nullable T> executeBlocking(Callable callable, boolean b) { - return null; - } - - @Override - @Deprecated - public Future<@Nullable T> executeBlocking(Handler> handler, boolean b) { - return null; - } - - @Override - public @Nullable JsonObject config() { - return null; - } - - @Override - public boolean isEventLoopContext() { - return false; - } - - @Override - public boolean isWorkerContext() { - return false; - } - - @Override - public ThreadingModel threadingModel() { - return null; - } -} diff --git a/foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/log/LogCollector.java b/foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/log/LogCollector.java index a01032939ec..5b435b89829 100644 --- a/foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/log/LogCollector.java +++ b/foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/log/LogCollector.java @@ -35,17 +35,22 @@ public class LogCollector implements Closeable { List events = new ArrayList<>(); - Appender appender = new AbstractAppender("LogCollector", null, PatternLayout.createDefaultLayout(), true, - Property.EMPTY_ARRAY) { - @Override - public void append(LogEvent event) { - events.add(event); - } - }; + Appender appender; + + String appenderName; public LogCollector() { LoggerContext ctx = (LoggerContext) LogManager.getContext(false); Configuration config = ctx.getConfiguration(); + appenderName = "LogCollector" + System.nanoTime(); + appender = new AbstractAppender(appenderName, null, PatternLayout.createDefaultLayout(), + true, + Property.EMPTY_ARRAY) { + @Override + public void append(LogEvent event) { + events.add(event); + } + }; appender.start(); config.getRootLogger().addAppender(appender, Level.ALL, null); ctx.updateLoggers(config); @@ -84,11 +89,11 @@ public List getThrowableMessages() { .collect(Collectors.toList()); } - public void teardown() { + public void tearDown() { LoggerContext ctx = (LoggerContext) LogManager.getContext(false); Configuration config = ctx.getConfiguration(); appender.stop(); - config.getRootLogger().removeAppender("LogCollector"); + config.getRootLogger().removeAppender(appenderName); ctx.updateLoggers(config); } @@ -98,6 +103,6 @@ public void clear() { @Override public void close() { - teardown(); + tearDown(); } } diff --git a/foundations/foundation-vertx/pom.xml b/foundations/foundation-vertx/pom.xml index 921b0892414..24556f590f7 100644 --- a/foundations/foundation-vertx/pom.xml +++ b/foundations/foundation-vertx/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb foundations - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT foundation-vertx Java Chassis::Foundations::Vertx diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/AddressResolverConfig.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/AddressResolverConfig.java index 8b99960be30..2d4ee389642 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/AddressResolverConfig.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/AddressResolverConfig.java @@ -109,7 +109,7 @@ private static int getPositiveIntProperty(int defaultValue, String... keys) { for (String key : keys) { Integer val = LegacyPropertyFactory.getProperty(key, Integer.class); if (val != null && val <= 0) { - LOGGER.warn("Address resover key:{}'s value:{} is not positive, please check!", key, val); + LOGGER.warn("Address resolver key:{}'s value:{} is not positive, please check!", key, val); continue; } if (val != null) { diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/SharedVertxFactory.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/SharedVertxFactory.java index 9803582459c..9f2d3af797b 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/SharedVertxFactory.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/SharedVertxFactory.java @@ -64,7 +64,7 @@ public static Vertx getSharedVertx(Environment environment) { private static Vertx createSharedVertx(Environment environment, String name) { SharedVertxInfo info = new SharedVertxInfo(environment); - Vertx vertx = VertxUtils.init(name, info.vertxOptions); + Vertx vertx = VertxUtils.init(name, info.vertxOptions, info.metricsFactory); info.metricsFactory.setVertx(vertx, info.vertxOptions); vertx.sharedData().getLocalMap(LOCAL_MAP_NAME).put(INFO, info); diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/VertxUtils.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/VertxUtils.java index 43094de2a35..5eceac0b24d 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/VertxUtils.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/VertxUtils.java @@ -38,14 +38,17 @@ import io.netty.buffer.ByteBuf; import io.vertx.core.AbstractVerticle; import io.vertx.core.DeploymentOptions; +import io.vertx.core.Future; import io.vertx.core.Verticle; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.buffer.Buffer; -import io.vertx.core.file.impl.FileResolverImpl; -import io.vertx.core.impl.VertxBuilder; +import io.vertx.core.impl.SysProps; import io.vertx.core.impl.VertxThread; +import io.vertx.core.internal.VertxBootstrap; +import io.vertx.core.spi.VertxMetricsFactory; import io.vertx.core.spi.VertxThreadFactory; +import io.vertx.core.transport.Transport; /** * VertxUtils @@ -90,12 +93,13 @@ public static Map blockDeploy(Vertx Map result = new HashMap<>(); CountDownLatch latch = new CountDownLatch(1); - vertx.deployVerticle(cls.getName(), options, ar -> { - result.put("code", ar.succeeded()); + Future future = vertx.deployVerticle(cls.getName(), options); + future.onComplete((success, failure) -> { + result.put("code", failure == null); - if (ar.failed()) { - result.put("message", ar.cause().getMessage()); - LOGGER.error("deploy vertx failed, cause ", ar.cause()); + if (failure != null) { + result.put("message", failure.getMessage()); + LOGGER.error("deploy vertx failed, cause ", failure); } latch.countDown(); @@ -106,11 +110,12 @@ public static Map blockDeploy(Vertx return result; } - public static Vertx getOrCreateVertxByName(String name, VertxOptions vertxOptions) { - return vertxMap.computeIfAbsent(name, vertxName -> init(vertxName, vertxOptions)); + public static Vertx getOrCreateVertxByName(String name, VertxOptions vertxOptions, + VertxMetricsFactory metricsFactory) { + return vertxMap.computeIfAbsent(name, vertxName -> init(name, vertxOptions, metricsFactory)); } - public static Vertx init(String name, VertxOptions vertxOptions) { + public static Vertx init(String name, VertxOptions vertxOptions, VertxMetricsFactory metricsFactory) { if (vertxOptions == null) { vertxOptions = new VertxOptions(); } @@ -123,14 +128,31 @@ public static Vertx init(String name, VertxOptions vertxOptions) { configureVertxFileCaching(vertxOptions); - return new VertxBuilder(vertxOptions).threadFactory(new VertxThreadFactory() { - @Override - public VertxThread newVertxThread(Runnable target, String threadName, boolean worker, long maxExecTime, - TimeUnit maxExecTimeUnit) { - return VertxThreadFactory.super - .newVertxThread(target, name + "-" + threadName, worker, maxExecTime, maxExecTimeUnit); - } - }).init().vertx(); + VertxBootstrap bootstrap = bootstrap(vertxOptions, metricsFactory) + .threadFactory(new VertxThreadFactory() { + @Override + public VertxThread newVertxThread(Runnable target, String threadName, boolean worker, long maxExecTime, + TimeUnit maxExecTimeUnit) { + return VertxThreadFactory.super + .newVertxThread(target, name + "-" + threadName, worker, maxExecTime, maxExecTimeUnit); + } + }); + + return bootstrap.init().vertx(); + } + + private static VertxBootstrap bootstrap(VertxOptions options, VertxMetricsFactory metricsFactory) { + VertxBootstrap bootstrap = VertxBootstrap.create(); + bootstrap.options(options); + bootstrap.metricsFactory(metricsFactory); + Transport tr; + if (options.getPreferNativeTransport()) { + tr = Transport.nativeTransport(); + } else { + tr = Transport.NIO; + } + bootstrap.transport(tr.implementation()); + return bootstrap; } /** @@ -138,7 +160,7 @@ public VertxThread newVertxThread(Runnable target, String threadName, boolean wo */ private static void configureVertxFileCaching(VertxOptions vertxOptions) { boolean disableFileCPResolving = LegacyPropertyFactory - .getBooleanProperty(FileResolverImpl.DISABLE_CP_RESOLVING_PROP_NAME, true); + .getBooleanProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, true); vertxOptions.getFileSystemOptions().setClassPathResolvingEnabled(!disableFileCPResolving); } @@ -178,15 +200,17 @@ public static CompletableFuture closeVertxByName(String name) { return future; } - vertx.close(ar -> { - if (ar.succeeded()) { + Future closeFuture = vertx.close(); + closeFuture.onComplete((succ, fail) -> { + if (fail == null) { LOGGER.info("Success to close vertx {}.", name); future.complete(null); return; } - future.completeExceptionally(ar.cause()); + future.completeExceptionally(fail); }); + return future; } @@ -201,8 +225,9 @@ public static void blockCloseVertxByName(String name) { public static void blockCloseVertx(Vertx vertx) { CountDownLatch latch = new CountDownLatch(1); - vertx.close(ar -> { - if (ar.succeeded()) { + Future closeFuture = vertx.close(); + closeFuture.onComplete((succ, fail) -> { + if (fail == null) { LOGGER.info("Success to close vertx {}.", vertx); } else { LOGGER.info("Failed to close vertx {}.", vertx); diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClientOptionsSPI.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClientOptionsSPI.java index abac2283316..83bf28db9ca 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClientOptionsSPI.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClientOptionsSPI.java @@ -125,15 +125,12 @@ static HttpClientOptions createHttpClientOptions(HttpClientOptionsSPI spi) { httpClientOptions.setProtocolVersion(spi.getHttpVersion()); httpClientOptions.setDecompressionSupported(spi.isTryUseCompression()); - httpClientOptions.setMaxWaitQueueSize(spi.getMaxWaitQueueSize()); - httpClientOptions.setMaxPoolSize(spi.getMaxPoolSize()); httpClientOptions.setKeepAlive(spi.isKeepAlive()); httpClientOptions.setMaxHeaderSize(spi.getMaxHeaderSize()); if (spi.getHttpVersion() == HttpVersion.HTTP_2) { httpClientOptions.setHttp2ClearTextUpgrade(false); httpClientOptions.setHttp2MultiplexingLimit(spi.getHttp2MultiplexingLimit()); - httpClientOptions.setHttp2MaxPoolSize(spi.getHttp2MaxPoolSize()); httpClientOptions.setHttp2KeepAliveTimeout(spi.getKeepAliveTimeout()); } else { httpClientOptions.setKeepAliveTimeout(spi.getKeepAliveTimeout()); diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClientPoolFactory.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClientPoolFactory.java index b9f4b34e033..69f15e6e397 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClientPoolFactory.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClientPoolFactory.java @@ -5,9 +5,7 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * * http://www.apache.org/licenses/LICENSE-2.0 - * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -24,6 +22,7 @@ import io.vertx.core.Context; import io.vertx.core.http.HttpClient; import io.vertx.core.http.HttpClientOptions; +import io.vertx.core.http.PoolOptions; // execute in vertx context public class HttpClientPoolFactory implements ClientPoolFactory { @@ -31,13 +30,18 @@ public class HttpClientPoolFactory implements ClientPoolFactory { LOGGER.debug("http connection connected, local:{}, remote:{}.", connection.localAddress(), connection.remoteAddress()); @@ -46,7 +50,7 @@ public HttpClientWithContext createClientPool(Context context) { connection.localAddress(), connection.remoteAddress()) ); connection.exceptionHandler(e -> - LOGGER.info("http connection exception, local:{}, remote:{}.", + LOGGER.error("http connection exception, local:{}, remote:{}.", connection.localAddress(), connection.remoteAddress(), e) ); }).build(); diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClients.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClients.java index 9eb29816483..b1ef46436ec 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClients.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/http/HttpClients.java @@ -37,6 +37,7 @@ import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.dns.AddressResolverOptions; +import io.vertx.core.http.PoolOptions; import io.vertx.core.http.WebSocketClient; /** @@ -70,8 +71,12 @@ public static void destroy() { private static ClientPoolManager createClientPoolManager(HttpClientOptionsSPI option) { Vertx vertx = getOrCreateVertx(option); + PoolOptions poolOptions = new PoolOptions(); + poolOptions.setMaxWaitQueueSize(option.getMaxWaitQueueSize()); + poolOptions.setHttp1MaxSize(option.getMaxPoolSize()); + poolOptions.setHttp2MaxSize(option.getHttp2MaxPoolSize()); ClientPoolManager clientPoolManager = new ClientPoolManager<>(vertx, - new HttpClientPoolFactory(HttpClientOptionsSPI.createHttpClientOptions(option))); + new HttpClientPoolFactory(HttpClientOptionsSPI.createHttpClientOptions(option), poolOptions)); DeploymentOptions deployOptions = VertxUtils.createClientDeployOptions(clientPoolManager, option.getInstanceCount()) @@ -103,7 +108,7 @@ private static Vertx getOrCreateVertx(HttpClientOptionsSPI option) { .setEventLoopPoolSize(option.getEventLoopPoolSize()); // Maybe we can deploy only one vert.x for the application. However this has did it like this. - return VertxUtils.getOrCreateVertxByName(option.clientName(), vertxOptions); + return VertxUtils.getOrCreateVertxByName(option.clientName(), vertxOptions, null); } /** diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/AbstractTcpClientPackage.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/AbstractTcpClientPackage.java index 763ba5e3daf..ef6717f8968 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/AbstractTcpClientPackage.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/AbstractTcpClientPackage.java @@ -27,9 +27,9 @@ public static long getAndIncRequestId() { return reqId.getAndIncrement(); } - private long msRequestTimeout; + private volatile long msRequestTimeout; - private long finishWriteToBuffer; + private volatile long finishWriteToBuffer; protected long msgId = getAndIncRequestId(); diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/NetClientWrapper.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/NetClientWrapper.java index a36d80c246c..ce47126ee47 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/NetClientWrapper.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/NetClientWrapper.java @@ -16,8 +16,7 @@ */ package org.apache.servicecomb.foundation.vertx.client.tcp; -import io.vertx.core.AsyncResult; -import io.vertx.core.Handler; +import io.vertx.core.Future; import io.vertx.core.Vertx; import io.vertx.core.net.NetClient; import io.vertx.core.net.NetSocket; @@ -50,12 +49,11 @@ public TcpClientConfig getClientConfig(boolean ssl) { return normalClientConfig; } - public void connect(boolean ssl, int port, String host, Handler> connectHandler) { + public Future connect(boolean ssl, int port, String host) { if (ssl) { - sslNetClient.connect(port, host, connectHandler); - return; + return sslNetClient.connect(port, host); } - normalNetClient.connect(port, host, connectHandler); + return normalNetClient.connect(port, host); } } diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpClientConnection.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpClientConnection.java index d8800800ff6..db071e3c34f 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpClientConnection.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpClientConnection.java @@ -39,6 +39,7 @@ import io.vertx.core.AsyncResult; import io.vertx.core.Context; +import io.vertx.core.Future; import io.vertx.core.buffer.Buffer; import io.vertx.core.net.NetSocket; import io.vertx.core.net.impl.NetSocketImpl; @@ -61,7 +62,7 @@ enum Status { private final InetSocketAddress socketAddress; - private boolean localSupportLogin = false; + private volatile boolean localSupportLogin = false; private final boolean remoteSupportLogin; @@ -180,17 +181,17 @@ protected void connect() { this.status = Status.CONNECTING; LOGGER.info("connecting to address {}", socketAddress.toString()); - netClientWrapper.connect(endpoint.isSslEnabled(), + Future result = netClientWrapper.connect(endpoint.isSslEnabled(), socketAddress.getPort(), - socketAddress.getHostString(), - ar -> { - if (ar.succeeded()) { - onConnectSuccess(ar.result()); - return; - } - - onConnectFailed(ar.cause()); - }); + socketAddress.getHostString()); + result.onComplete((socket, fail) -> { + if (fail == null) { + onConnectSuccess(socket); + return; + } + + onConnectFailed(fail); + }); } private void onConnectSuccess(NetSocket socket) { diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/ReadStreamPart.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/ReadStreamPart.java index e6a7947eb2b..acd2fc1978a 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/ReadStreamPart.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/ReadStreamPart.java @@ -27,8 +27,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.vertx.core.AsyncResult; import io.vertx.core.Context; +import io.vertx.core.Future; import io.vertx.core.Vertx; import io.vertx.core.buffer.Buffer; import io.vertx.core.file.AsyncFile; @@ -82,15 +82,13 @@ public ReadStream getReadStream() { } /** - * - * @param writeStream * @return future of save action
* * important: WriteStream did not provide endHandler, so we can not know when will really finished write. * so the return future only means finished read from readStream. */ public CompletableFuture saveToWriteStream(WriteStream writeStream) { - return new PumpCommon().pump(context, readStream, writeStream, null); + return new PumpCommon().pump(readStream, writeStream, null); } public CompletableFuture saveAsBytes() { @@ -120,8 +118,6 @@ public CompletableFuture saveAs(Function converter) { } /** - * - * @param fileName * @return future of save to file, future complete means write to file finished */ public CompletableFuture saveToFile(String fileName) { @@ -132,9 +128,6 @@ public CompletableFuture saveToFile(String fileName) { } /** - * - * @param file - * @param openOptions * @return future of save to file, future complete means write to file finished */ public CompletableFuture saveToFile(File file, OpenOptions openOptions) { @@ -142,34 +135,37 @@ public CompletableFuture saveToFile(File file, OpenOptions openOptions) { context.runOnContext((v) -> { Vertx vertx = context.owner(); - vertx.fileSystem().open(file.getAbsolutePath(), openOptions, ar -> onFileOpened(file, ar, future)); + Future openFuture = vertx.fileSystem().open(file.getAbsolutePath(), openOptions); + openFuture.onComplete((s, f) -> onFileOpened(file, s, f, future)); }); return future; } - protected void onFileOpened(File file, AsyncResult ar, CompletableFuture future) { - if (ar.failed()) { - future.completeExceptionally(ar.cause()); + protected void onFileOpened(File file, AsyncFile asyncFile, Throwable failure, CompletableFuture future) { + if (failure != null) { + future.completeExceptionally(failure); return; } - AsyncFile asyncFile = ar.result(); CompletableFuture saveFuture = saveToWriteStream(asyncFile); - saveFuture.whenComplete((v, saveException) -> asyncFile.close(closeAr -> { - if (closeAr.failed()) { - LOGGER.error("Failed to close file {}.", file); - } - - // whatever close success or failed - // will not affect to result - // result just only related to write - if (saveException == null) { - future.complete(file); - return; - } - - future.completeExceptionally(saveException); - })); + saveFuture.whenComplete((v, saveException) -> { + Future result = asyncFile.close(); + result.onComplete((s, f) -> { + if (f != null) { + LOGGER.error("Failed to close file {}.", file); + } + + // whatever close success or failed + // will not affect to result + // result just only related to write + if (saveException == null) { + future.complete(file); + return; + } + + future.completeExceptionally(saveException); + }); + }); } } diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultClientMetrics.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultClientMetrics.java index c3893a2e60d..2bc9288857b 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultClientMetrics.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultClientMetrics.java @@ -17,16 +17,14 @@ package org.apache.servicecomb.foundation.vertx.metrics; -import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetric; -import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientTaskMetric; -import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultRequestMetric; - import io.vertx.core.spi.metrics.ClientMetrics; import io.vertx.core.spi.observability.HttpRequest; import io.vertx.core.spi.observability.HttpResponse; +import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetric; +import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultRequestMetric; public class DefaultClientMetrics implements - ClientMetrics { + ClientMetrics { private final DefaultClientEndpointMetric clientEndpointMetric; public DefaultClientMetrics(DefaultClientEndpointMetric clientEndpointMetric) { @@ -37,18 +35,6 @@ public DefaultClientEndpointMetric getClientEndpointMetric() { return this.clientEndpointMetric; } - @Override - public DefaultClientTaskMetric enqueueRequest() { - DefaultClientTaskMetric taskMetric = new DefaultClientTaskMetric(clientEndpointMetric); - taskMetric.enqueueRequest(); - return taskMetric; - } - - @Override - public void dequeueRequest(DefaultClientTaskMetric endpointMetric) { - endpointMetric.dequeueRequest(); - } - @Override public DefaultRequestMetric requestBegin(String uri, HttpRequest request) { DefaultRequestMetric requestMetric = new DefaultRequestMetric(this.clientEndpointMetric); diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpClientMetrics.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpClientMetrics.java index 59649948348..1279a4f8566 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpClientMetrics.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpClientMetrics.java @@ -18,7 +18,6 @@ import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetric; import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetricManager; -import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientTaskMetric; import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultRequestMetric; import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultTcpSocketMetric; @@ -26,7 +25,7 @@ import io.vertx.core.spi.metrics.HttpClientMetrics; public class DefaultHttpClientMetrics implements - HttpClientMetrics { + HttpClientMetrics { private static final String PROTOCOL = "http://"; private final DefaultClientEndpointMetricManager clientEndpointMetricManager; diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetrics.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetrics.java index ee345ed4e2b..c0b89a42eea 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetrics.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetrics.java @@ -18,23 +18,22 @@ import java.util.Map; -import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx; -import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetricManager; -import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultServerEndpointMetric; - import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.http.HttpClientOptions; import io.vertx.core.http.HttpServerOptions; -import io.vertx.core.metrics.impl.DummyVertxMetrics; import io.vertx.core.net.NetClientOptions; import io.vertx.core.net.NetServerOptions; import io.vertx.core.net.SocketAddress; import io.vertx.core.spi.metrics.HttpClientMetrics; import io.vertx.core.spi.metrics.HttpServerMetrics; import io.vertx.core.spi.metrics.TCPMetrics; +import io.vertx.core.spi.metrics.VertxMetrics; +import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx; +import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetricManager; +import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultServerEndpointMetric; -public class DefaultVertxMetrics extends DummyVertxMetrics { +public class DefaultVertxMetrics implements VertxMetrics { // to support listen multiple addresses, must use a map to manage the metric private final Map serverEndpointMetricMap = new ConcurrentHashMapEx<>(); @@ -61,7 +60,7 @@ public Map getServerEndpointMetricMap() { } @Override - public HttpClientMetrics createHttpClientMetrics(HttpClientOptions options) { + public HttpClientMetrics createHttpClientMetrics(HttpClientOptions options) { return new DefaultHttpClientMetrics(clientEndpointMetricManager); } diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetricsFactory.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetricsFactory.java index dca7cecca92..540a644b1e1 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetricsFactory.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetricsFactory.java @@ -55,7 +55,6 @@ public synchronized VertxMetrics metrics(VertxOptions options) { @Override public MetricsOptions newOptions() { MetricsOptionsEx metricsOptions = new MetricsOptionsEx(); - metricsOptions.setFactory(this); metricsOptions.setEnabled(true); return metricsOptions; } diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetric.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetric.java index cedd6ec6b32..ce618078957 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetric.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetric.java @@ -29,7 +29,7 @@ public class DefaultClientEndpointMetric extends DefaultEndpointMetric { // control if the metric instance will be expired // all invoker about incRefCount/isExpired, must lock: DefaultClientEndpointMetricManager // decRefCount no need to lock, because that only cause to be expired later. - private long lastNanoTime = System.nanoTime(); + private volatile long lastNanoTime = System.nanoTime(); public DefaultClientEndpointMetric(String address) { super(address); diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpParser.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpParser.java index a59004d62a1..4e79f69fca3 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpParser.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpParser.java @@ -19,16 +19,10 @@ import java.nio.charset.StandardCharsets; -import io.netty.buffer.ByteBuf; import io.vertx.core.Handler; import io.vertx.core.buffer.Buffer; import io.vertx.core.parsetools.RecordParser; -/** - * TcpParser - * - * - */ public class TcpParser implements Handler { public static final byte[] TCP_MAGIC; @@ -86,16 +80,17 @@ public boolean firstNEqual(byte[] a, byte[] b, int n) { protected void onParse(Buffer buffer) { switch (status) { case TCP_HEADER: - ByteBuf buf = buffer.getByteBuf(); - if (!firstNEqual(TCP_MAGIC, buf.array(), TCP_MAGIC.length)) { + if (!firstNEqual(TCP_MAGIC, buffer.getBytes(), TCP_MAGIC.length)) { reset(); return; } - buf.skipBytes(TCP_MAGIC.length); - msgId = buf.readLong(); - totalLen = buf.readInt(); - headerLen = buf.readInt(); + int index = TCP_MAGIC.length; + msgId = buffer.getLong(index); + index = index + 8; + totalLen = buffer.getInt(index); + index = index + 4; + headerLen = buffer.getInt(index); if (headerLen > totalLen || headerLen <= 0) { throw new IllegalStateException("possibly attack."); } diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpServer.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpServer.java index 3c0f604f9ae..8a960175ad8 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpServer.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpServer.java @@ -31,6 +31,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import io.vertx.core.Future; import io.vertx.core.Vertx; import io.vertx.core.net.NetServer; import io.vertx.core.net.NetServerOptions; @@ -81,15 +82,16 @@ public void init(Vertx vertx, String sslKey, AsyncResultCallback LOGGER.error("Unexpected error in server.", e)); InetSocketAddress socketAddress = endpointObject.getSocketAddress(); - netServer.listen(socketAddress.getPort(), socketAddress.getHostString(), ar -> { - if (ar.succeeded()) { + Future result = netServer.listen(socketAddress.getPort(), socketAddress.getHostString()); + result.onComplete((s, f) -> { + if (f == null) { callback.success(socketAddress); return; } // 监听失败 String msg = String.format("listen failed, address=%s", socketAddress); - callback.fail(new Exception(msg, ar.cause())); + callback.fail(new Exception(msg, f)); }); } diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/InputStreamToReadStream.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/InputStreamToReadStream.java index f1a5f83b2ce..580d460e5c0 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/InputStreamToReadStream.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/InputStreamToReadStream.java @@ -19,12 +19,11 @@ import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.netty.buffer.Unpooled; -import io.vertx.core.AsyncResult; import io.vertx.core.Context; import io.vertx.core.Handler; import io.vertx.core.Promise; @@ -40,7 +39,7 @@ public class InputStreamToReadStream implements ReadStream { private final InputStream inputStream; - private boolean closed; + private volatile boolean closed; private boolean paused; @@ -106,17 +105,20 @@ void doRead() throws IOException { } Buffer toBuffer() { - return Buffer.buffer(Unpooled.wrappedBuffer(bytes).writerIndex(read)); + return Buffer.buffer(Arrays.copyOf(bytes, read)); } } private synchronized void doRead() { if (!readInProgress) { readInProgress = true; - - context.executeBlocking(this::readInWorker, - true, - this::afterReadInEventloop); + Promise future = Promise.promise(); + context.executeBlocking(() -> { + readInWorker(future); + return null; + }, + true); + future.future().onComplete(this::afterReadInEventloop); } } @@ -135,14 +137,13 @@ public void handleException(Throwable e) { exceptionHandler.handle(e); } - private synchronized void afterReadInEventloop(AsyncResult ar) { - if (ar.failed()) { - handleException(ar.cause()); + private synchronized void afterReadInEventloop(ReadResult readResult, Throwable failure) { + if (failure != null) { + handleException(failure); return; } readInProgress = false; - ReadResult readResult = ar.result(); if (readResult.read < 0) { handleEnd(); return; diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/OutputStreamToWriteStream.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/OutputStreamToWriteStream.java index 95ea0b5076d..35681a723a8 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/OutputStreamToWriteStream.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/OutputStreamToWriteStream.java @@ -21,10 +21,10 @@ import java.util.Queue; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; import org.apache.servicecomb.foundation.common.io.AsyncCloseable; -import io.vertx.core.AsyncResult; import io.vertx.core.Context; import io.vertx.core.Future; import io.vertx.core.Handler; @@ -60,7 +60,7 @@ public class OutputStreamToWriteStream implements WriteStream, AsyncClos // we just need to flow control by pump, so use another size private final Queue buffers = new ConcurrentLinkedQueue<>(); - private int currentBufferCount; + private final AtomicInteger currentBufferCount = new AtomicInteger(); // just indicate if buffers is full, not control add logic // must >= SMALLEST_MAX_BUFFERS @@ -92,22 +92,20 @@ private void handleException(Throwable t) { @Override public synchronized Future write(Buffer data) { Promise result = Promise.promise(); - write(data, ar -> { - if (ar.failed()) { - handleException(ar.cause()); - } - result.complete(); - }); + write(data, result); return result.future(); } - @Override - public void write(Buffer data, Handler> handler) { - currentBufferCount++; + private void write(Buffer data, Promise future) { + currentBufferCount.incrementAndGet(); buffers.add(data); - context.executeBlocking(this::writeInWorker, - true, - handler); + context.executeBlocking( + () -> { + writeInWorker(future); + return null; + }, + true + ); } protected void writeInWorker(Promise future) { @@ -122,12 +120,13 @@ protected void writeInWorker(Promise future) { outputStream.write(buffer.getBytes()); synchronized (OutputStreamToWriteStream.this) { - currentBufferCount--; - Runnable action = (currentBufferCount == 0 && closedDeferred != null) ? closedDeferred : this::checkDrained; + currentBufferCount.decrementAndGet(); + Runnable action = (currentBufferCount.get() == 0 && closedDeferred != null) + ? closedDeferred : this::checkDrained; action.run(); } } catch (IOException e) { - currentBufferCount--; + currentBufferCount.decrementAndGet(); future.fail(e); return; } @@ -135,8 +134,8 @@ protected void writeInWorker(Promise future) { } @Override - public void end(Handler> handler) { - close(); + public Future end() { + return Future.fromCompletionStage(close()); } @Override @@ -148,7 +147,7 @@ public WriteStream setWriteQueueMaxSize(int maxSize) { @Override public synchronized boolean writeQueueFull() { - return currentBufferCount >= maxBuffers; + return currentBufferCount.get() >= maxBuffers; } @Override @@ -158,7 +157,7 @@ public synchronized WriteStream drainHandler(Handler handler) { } private synchronized void checkDrained() { - if (drainHandler != null && currentBufferCount <= drainMark) { + if (drainHandler != null && currentBufferCount.get() <= drainMark) { Handler handler = drainHandler; drainHandler = null; handler.handle(null); @@ -186,7 +185,7 @@ private synchronized CompletableFuture closeInternal() { closed = true; CompletableFuture future = new CompletableFuture<>(); - if (currentBufferCount == 0) { + if (currentBufferCount.get() == 0) { doClose(future); } else { closedDeferred = () -> doClose(future); diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/PumpCommon.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/PumpCommon.java index 5b70f72766e..ae4b5bac727 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/PumpCommon.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/PumpCommon.java @@ -20,27 +20,23 @@ import org.apache.servicecomb.foundation.common.io.AsyncCloseable; -import io.vertx.core.Context; +import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.core.buffer.Buffer; import io.vertx.core.http.HttpClientResponse; -import io.vertx.core.streams.Pump; import io.vertx.core.streams.ReadStream; import io.vertx.core.streams.WriteStream; +import io.vertx.core.streams.impl.PipeImpl; public class PumpCommon { /** - * - * @param context - * @param readStream - * @param writeStream * @return future of save action
*

important: *

if writeStream is AsyncCloseable, future means write complete *

if writeStream is not AsyncCloseable, future only means read complete */ @SuppressWarnings("unchecked") - public CompletableFuture pump(Context context, ReadStream readStream, WriteStream writeStream, + public CompletableFuture pump(ReadStream readStream, WriteStream writeStream, Handler throwableHandler) { CompletableFuture readFuture = new CompletableFuture<>(); @@ -62,17 +58,18 @@ public CompletableFuture pump(Context context, ReadStream readStre readFuture.completeExceptionally(e); }); readStream.exceptionHandler(readFuture::completeExceptionally); - // just means read finished, not means write finished - readStream.endHandler(readFuture::complete); - // if readStream(HttpClientResponse) and writeStream(HttpServerResponse) - // belongs to difference eventloop - // maybe will cause deadlock - // if happened, vertx will print deadlock stacks - Pump.pump(readStream, writeStream).start(); - context.runOnContext(v -> readStream.resume()); + Future pipeResult = new PipeImpl<>(readStream).endOnComplete(false).to(writeStream); - if (!AsyncCloseable.class.isInstance(writeStream)) { + pipeResult.onComplete((s) -> readFuture.complete(null), + (f) -> { + if (throwableHandler != null) { + throwableHandler.handle(f); + } + readFuture.completeExceptionally(f); + }); + + if (!(writeStream instanceof AsyncCloseable)) { return readFuture; } diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/PumpFromPart.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/PumpFromPart.java index ba7b3182087..2c5284e12dc 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/PumpFromPart.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/PumpFromPart.java @@ -69,7 +69,7 @@ private CompletableFuture> prepareReadStream() { public CompletableFuture toWriteStream(WriteStream writeStream, Handler throwableHandler) { return prepareReadStream() - .thenCompose(readStream -> new PumpCommon().pump(context, readStream, writeStream, throwableHandler)) + .thenCompose(readStream -> new PumpCommon().pump(readStream, writeStream, throwableHandler)) .whenComplete((v, e) -> { if (e != null) { LOGGER.error("to write stream failed.", e); diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/tcp/TcpConnection.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/tcp/TcpConnection.java index 15e6977d2eb..fcc22bfd7c9 100644 --- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/tcp/TcpConnection.java +++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/tcp/TcpConnection.java @@ -77,7 +77,7 @@ public NetSocket getNetSocket() { public void initNetSocket(NetSocketImpl netSocket) { this.netSocket = netSocket; - this.context = netSocket.getContext(); + this.context = netSocket.context(); } public void write(Buffer buf) { diff --git a/foundations/foundation-vertx/src/test/java/io/vertx/ext/web/impl/TestHttpServerRequestUtils.java b/foundations/foundation-vertx/src/test/java/io/vertx/ext/web/impl/TestHttpServerRequestUtils.java deleted file mode 100644 index 7297a866b2f..00000000000 --- a/foundations/foundation-vertx/src/test/java/io/vertx/ext/web/impl/TestHttpServerRequestUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.vertx.ext.web.impl; - -import org.apache.servicecomb.foundation.vertx.http.VertxServerRequestToHttpServletRequest; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import io.vertx.core.http.impl.HttpServerRequestInternal; -import io.vertx.core.net.HostAndPort; -import io.vertx.ext.web.AllowForwardHeaders; -import io.vertx.ext.web.RequestBody; -import io.vertx.ext.web.RoutingContext; - -// HttpServerRequestWrapper is a package visible class, so put this test in package io.vertx.ext.web.impl -public class TestHttpServerRequestUtils { - @Test - public void testVertxServerRequestToHttpServletRequest() { - RoutingContext context = Mockito.mock(RoutingContext.class); - HttpServerRequestInternal request = Mockito.mock(HttpServerRequestInternal.class); - HttpServerRequestWrapper wrapper = new HttpServerRequestWrapper(request, AllowForwardHeaders.NONE, null); - Mockito.when(request.scheme()).thenReturn("http"); - Mockito.when(context.request()).thenReturn(wrapper); - Mockito.when(request.authority()).thenReturn(HostAndPort.create("localhost", 8080)); - RequestBody requestBody = Mockito.mock(RequestBody.class); - Mockito.when(context.body()).thenReturn(requestBody); - - VertxServerRequestToHttpServletRequest reqEx = new VertxServerRequestToHttpServletRequest(context, "abc"); - Assertions.assertEquals("abc", reqEx.getRequestURI()); - } -} diff --git a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestSharedVertxFactory.java b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestSharedVertxFactory.java index 10cc0827a0f..8e77a256251 100644 --- a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestSharedVertxFactory.java +++ b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestSharedVertxFactory.java @@ -23,7 +23,7 @@ import org.mockito.Mockito; import org.springframework.core.env.Environment; -import io.vertx.core.file.impl.FileResolverImpl; +import io.vertx.core.impl.SysProps; public class TestSharedVertxFactory { Environment environment = Mockito.mock(Environment.class); @@ -32,7 +32,7 @@ public class TestSharedVertxFactory { public void setUp() { Mockito.when(environment.getProperty("servicecomb.transport.eventloop.size", int.class, -1)) .thenReturn(-1); - Mockito.when(environment.getProperty(FileResolverImpl.DISABLE_CP_RESOLVING_PROP_NAME, boolean.class, true)) + Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true)) .thenReturn(true); LegacyPropertyFactory.setEnvironment(environment); } diff --git a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestStream.java b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestStream.java index ea3a797da37..af3e2078c90 100644 --- a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestStream.java +++ b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestStream.java @@ -31,7 +31,7 @@ public class TestStream { @Test public void testBufferInputStream() { Buffer obuf = Buffer.buffer(DIRECT_BUFFER_SIZE); - obuf.appendBytes(("testss").getBytes()); + obuf.appendBytes(("tests1").getBytes()); @SuppressWarnings("resource") BufferInputStream oBufferInputStream = new BufferInputStream(obuf); diff --git a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestVertxUtils.java b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestVertxUtils.java index f3762fe5f37..9f966cbcbde 100644 --- a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestVertxUtils.java +++ b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestVertxUtils.java @@ -38,14 +38,14 @@ import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import io.vertx.core.buffer.Buffer; -import io.vertx.core.file.impl.FileResolverImpl; +import io.vertx.core.impl.SysProps; public class TestVertxUtils { Environment environment = Mockito.mock(Environment.class); @BeforeEach public void setUp() { - Mockito.when(environment.getProperty(FileResolverImpl.DISABLE_CP_RESOLVING_PROP_NAME, boolean.class, true)) + Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true)) .thenReturn(true); LegacyPropertyFactory.setEnvironment(environment); @@ -53,7 +53,7 @@ public void setUp() { @Test public void testGetOrCreateVertx() throws InterruptedException { - Vertx vertx = VertxUtils.getOrCreateVertxByName("ut", null); + Vertx vertx = VertxUtils.getOrCreateVertxByName("ut", null, null); Holder name = new Holder<>(); CountDownLatch latch = new CountDownLatch(1); @@ -70,25 +70,25 @@ public void testGetOrCreateVertx() throws InterruptedException { @Test public void testCreateVertxWithFileCPResolving() { // create .vertx folder - Mockito.when(environment.getProperty(FileResolverImpl.DISABLE_CP_RESOLVING_PROP_NAME, boolean.class, true)) + Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true)) .thenReturn(false); deleteCacheFile(); - VertxUtils.getOrCreateVertxByName("testCreateVertxWithFileCPResolvingFalse", null); + VertxUtils.getOrCreateVertxByName("testCreateVertxWithFileCPResolvingFalse", null, null); Assertions.assertTrue(isCacheFileExists()); VertxUtils.blockCloseVertxByName("testCreateVertxWithFileCPResolvingFalse"); // don't create .vertx folder deleteCacheFile(); Assertions.assertFalse(isCacheFileExists()); - Mockito.when(environment.getProperty(FileResolverImpl.DISABLE_CP_RESOLVING_PROP_NAME, boolean.class, true)) + Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true)) .thenReturn(true); - VertxUtils.getOrCreateVertxByName("testCreateVertxWithFileCPResolvingTrue", null); + VertxUtils.getOrCreateVertxByName("testCreateVertxWithFileCPResolvingTrue", null, null); Assertions.assertFalse(isCacheFileExists()); VertxUtils.blockCloseVertxByName("testCreateVertxWithFileCPResolvingTrue"); } private void deleteCacheFile() { - String cacheDirBase = System.getProperty(FileResolverImpl.CACHE_DIR_BASE_PROP_NAME, + String cacheDirBase = System.getProperty(SysProps.FILE_CACHE_DIR.name, System.getProperty("java.io.tmpdir", ".")); File folder = new File(cacheDirBase); File[] files = folder.listFiles(); @@ -100,7 +100,7 @@ private void deleteCacheFile() { } private boolean isCacheFileExists() { - String cacheDirBase = System.getProperty(FileResolverImpl.CACHE_DIR_BASE_PROP_NAME, + String cacheDirBase = System.getProperty(SysProps.FILE_CACHE_DIR.name, System.getProperty("java.io.tmpdir", ".")); File folder = new File(cacheDirBase); File[] files = folder.listFiles(); @@ -114,7 +114,7 @@ private boolean isCacheFileExists() { @Test public void testVertxUtilsInitNullOptions() { - Vertx vertx = VertxUtils.init(null, null); + Vertx vertx = VertxUtils.init(null, null, null); Assertions.assertNotEquals(null, vertx); VertxUtils.blockCloseVertx(vertx); } @@ -123,7 +123,7 @@ public void testVertxUtilsInitNullOptions() { public void testVertxUtilsInitWithOptions() { VertxOptions oOptions = new VertxOptions(); - Vertx vertx = VertxUtils.init(null, oOptions); + Vertx vertx = VertxUtils.init(null, oOptions, null); Assertions.assertNotEquals(null, vertx); VertxUtils.blockCloseVertx(vertx); } diff --git a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/tcp/TestNetClientWrapper.java b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/tcp/TestNetClientWrapper.java deleted file mode 100644 index adbcd3e8138..00000000000 --- a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/tcp/TestNetClientWrapper.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.servicecomb.foundation.vertx.client.tcp; - - -import java.util.ArrayList; -import java.util.List; - -import org.hamcrest.MatcherAssert; -import org.hamcrest.Matchers; -import org.junit.Before; -import org.junit.Test; - -import io.vertx.core.AsyncResult; -import io.vertx.core.Handler; -import io.vertx.core.Promise; -import io.vertx.core.Vertx; -import io.vertx.core.net.NetClient; -import io.vertx.core.net.NetSocket; -import mockit.Expectations; -import mockit.Mock; -import mockit.MockUp; -import mockit.Mocked; -import org.junit.jupiter.api.Assertions; - -public class TestNetClientWrapper { - @Mocked - Vertx vertx; - - @Mocked - TcpClientConfig normalClientConfig; - - @Mocked - NetClient normalNetClient; - - @Mocked - TcpClientConfig sslClientConfig; - - @Mocked - NetClient sslNetClient; - - NetClientWrapper netClientWrapper; - - @Before - public void setup() { - new Expectations() { - { - vertx.createNetClient(normalClientConfig); - result = normalNetClient; - vertx.createNetClient(sslClientConfig); - result = sslNetClient; - } - }; - netClientWrapper = new NetClientWrapper(vertx, normalClientConfig, sslClientConfig); - } - - @Test - public void getClientConfig() { - Assertions.assertSame(normalClientConfig, netClientWrapper.getClientConfig(false)); - Assertions.assertSame(sslClientConfig, netClientWrapper.getClientConfig(true)); - } - - @Test - public void connect(@Mocked NetSocket normalSocket, @Mocked NetSocket sslSocket) { - int port = 8000; - String host = "localhost"; - - Promise promiseConnect = Promise.promise(); - new MockUp(normalNetClient) { - @Mock - NetClient connect(int port, String host, Handler> connectHandler) { - promiseConnect.complete(normalSocket); - connectHandler.handle(promiseConnect.future()); - return null; - } - }; - - Promise sslPromiseConnect = Promise.promise(); - new MockUp(sslNetClient) { - @Mock - NetClient connect(int port, String host, Handler> connectHandler) { - sslPromiseConnect.complete(sslSocket); - connectHandler.handle(sslPromiseConnect.future()); - return null; - } - }; - - List socks = new ArrayList<>(); - netClientWrapper.connect(false, port, host, asyncSocket -> socks.add(asyncSocket.result())); - netClientWrapper.connect(true, port, host, asyncSocket -> socks.add(asyncSocket.result())); - - MatcherAssert.assertThat(socks, Matchers.contains(normalSocket, sslSocket)); - } -} diff --git a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/tcp/TestTcpClientConnection.java b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/tcp/TestTcpClientConnection.java index de87122f1ba..f072d962000 100644 --- a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/tcp/TestTcpClientConnection.java +++ b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/tcp/TestTcpClientConnection.java @@ -28,8 +28,8 @@ import org.junit.jupiter.api.Assertions; import io.netty.buffer.ByteBuf; -import io.vertx.core.AsyncResult; import io.vertx.core.Context; +import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.core.Promise; import io.vertx.core.buffer.Buffer; @@ -195,9 +195,9 @@ public void connect_success(@Mocked NetSocketImpl netSocket) { Promise promise = Promise.promise(); new MockUp(netClientWrapper) { @Mock - void connect(boolean ssl, int port, String host, Handler> connectHandler) { + public Future connect(boolean ssl, int port, String host) { promise.complete(netSocket); - connectHandler.handle(promise.future()); + return promise.future(); } }; @@ -216,9 +216,9 @@ public void connect_failed() { RuntimeException error = new RuntimeExceptionWithoutStackTrace(); new MockUp(netClientWrapper) { @Mock - void connect(boolean ssl, int port, String host, Handler> connectHandler) { + public Future connect(boolean ssl, int port, String host) { promise.fail(error); - connectHandler.handle(promise.future()); + return promise.future(); } }; diff --git a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/tcp/TestTcpClientConnectionPool.java b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/tcp/TestTcpClientConnectionPool.java deleted file mode 100644 index dfaf8ec60a2..00000000000 --- a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/client/tcp/TestTcpClientConnectionPool.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.servicecomb.foundation.vertx.client.tcp; - -import io.vertx.core.impl.ContextInternal; -import io.vertx.core.impl.VertxInternal; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -public class TestTcpClientConnectionPool { - - TcpClientConnectionPool pool; - - @BeforeEach - public void setup() { - ContextInternal context = Mockito.mock(ContextInternal.class); - VertxInternal vertx = Mockito.mock(VertxInternal.class); - Mockito.when(context.owner()).thenReturn(vertx); - NetClientWrapper netClientWrapper = Mockito.mock(NetClientWrapper.class); - pool = new TcpClientConnectionPool(context, netClientWrapper); - } - - @Test - public void create() { - Assertions.assertTrue(pool.create("rest://localhost:8765") instanceof TcpClientConnection); - } -} diff --git a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestReadStreamPart.java b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestReadStreamPart.java deleted file mode 100644 index 03d425e353c..00000000000 --- a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestReadStreamPart.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.servicecomb.foundation.vertx.http; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.UUID; -import java.util.concurrent.ExecutionException; - -import jakarta.ws.rs.core.HttpHeaders; - -import org.apache.commons.io.FileUtils; -import org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace; -import org.apache.servicecomb.foundation.vertx.stream.InputStreamToReadStream; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - -import io.vertx.core.Handler; -import io.vertx.core.Vertx; -import io.vertx.core.buffer.Buffer; -import io.vertx.core.file.FileSystemException; -import io.vertx.core.file.OpenOptions; -import io.vertx.core.http.HttpClientResponse; -import io.vertx.core.impl.SyncContext; -import io.vertx.core.impl.VertxInternal; -import io.vertx.core.streams.WriteStream; -import mockit.Expectations; -import mockit.Mock; -import mockit.MockUp; -import mockit.Mocked; - -public class TestReadStreamPart { - static Vertx vertx = Vertx.vertx(); - - static SyncContext context = new SyncContext(); - - static String src = "src"; - - static InputStream inputStream = new ByteArrayInputStream(src.getBytes()); - - InputStreamToReadStream readStream = new InputStreamToReadStream(context, inputStream, true); - - ReadStreamPart part = new ReadStreamPart(context, readStream); - - @Before - public void setup() throws IOException { - context.setOwner((VertxInternal) vertx); - inputStream.reset(); - } - - @AfterClass - public static void teardown() { - vertx.close(); - } - - @Test - public void constructFromHttpClientResponse_noContentType(@Mocked HttpClientResponse httpClientResponse) { - new Expectations() { - { - httpClientResponse.getHeader(HttpHeaders.CONTENT_DISPOSITION); - result = "xx;filename=name.txt"; - httpClientResponse.getHeader(HttpHeaders.CONTENT_TYPE); - result = null; - } - }; - - part = new ReadStreamPart(context, httpClientResponse); - - Assertions.assertEquals("name.txt", part.getSubmittedFileName()); - Assertions.assertEquals("text/plain", part.getContentType()); - } - - @Test - public void constructFromHttpClientResponse_hasContentType(@Mocked HttpClientResponse httpClientResponse) { - new Expectations() { - { - httpClientResponse.getHeader(HttpHeaders.CONTENT_DISPOSITION); - result = "xx;filename=name.txt"; - httpClientResponse.getHeader(HttpHeaders.CONTENT_TYPE); - result = "type"; - } - }; - - part = new ReadStreamPart(context, httpClientResponse); - - Assertions.assertEquals("name.txt", part.getSubmittedFileName()); - Assertions.assertEquals("type", part.getContentType()); - } - - @Test - public void saveToWriteStream() throws InterruptedException, ExecutionException { - Buffer buf = Buffer.buffer(); - WriteStream writeStream = new MockUp>() { - @Mock - WriteStream write(Buffer data) { - buf.appendBuffer(data); - return null; - } - }.getMockInstance(); - - part.saveToWriteStream(writeStream).get(); - - Assertions.assertEquals(src, buf.toString()); - } - - @Test - public void saveToWriteStream_writeException() throws InterruptedException, ExecutionException { - RuntimeException error = new RuntimeExceptionWithoutStackTrace(); - WriteStream writeStream = new MockUp>() { - Handler exceptionHandler; - - @Mock - WriteStream exceptionHandler(Handler handler) { - this.exceptionHandler = handler; - return null; - } - - @Mock - WriteStream write(Buffer data) { - exceptionHandler.handle(error); - return null; - } - }.getMockInstance(); - - ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> part.saveToWriteStream(writeStream).get()); - Assertions.assertTrue(exception.getCause() instanceof RuntimeException); - } - - @Test - public void saveToWrite_readException(@Mocked WriteStream writeStream) { - RuntimeException error = new RuntimeExceptionWithoutStackTrace(); - new MockUp(inputStream) { - @Mock - int read(byte[] b) throws IOException { - throw error; - } - }; - - ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> part.saveToWriteStream(writeStream).get()); - Assertions.assertTrue(exception.getCause() instanceof RuntimeException); - } - - @Test - public void saveAsBytes() throws InterruptedException, ExecutionException { - Assertions.assertArrayEquals(src.getBytes(), part.saveAsBytes().get()); - } - - @Test - public void saveAsString() throws InterruptedException, ExecutionException { - Assertions.assertEquals(src, part.saveAsString().get()); - } - - @Test - public void saveToFile() throws InterruptedException, ExecutionException, IOException { - File dir = new File("target/notExist-" + UUID.randomUUID()); - File file = new File(dir, "a.txt"); - - Assertions.assertFalse(dir.exists()); - - part.saveToFile(file.getAbsolutePath()).get(); - - Assertions.assertEquals(src, FileUtils.readFileToString(file, StandardCharsets.UTF_8)); - - FileUtils.forceDelete(dir); - Assertions.assertFalse(dir.exists()); - } - - @Test - public void saveToFile_notExist_notCreate() throws InterruptedException, ExecutionException, IOException { - File dir = new File("target/notExist-" + UUID.randomUUID()); - File file = new File(dir, "a.txt"); - - Assertions.assertFalse(dir.exists()); - - ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> { - OpenOptions openOptions = new OpenOptions().setCreateNew(false); - part.saveToFile(file, openOptions).get(); - }); - Assertions.assertTrue(exception.getCause() instanceof FileSystemException); - } -} diff --git a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxServerResponseToHttpServletResponse.java b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxServerResponseToHttpServletResponse.java deleted file mode 100644 index 1ab6d81bc1c..00000000000 --- a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxServerResponseToHttpServletResponse.java +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.servicecomb.foundation.vertx.http; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import org.apache.commons.io.FileUtils; -import org.apache.servicecomb.foundation.common.http.HttpStatus; -import org.apache.servicecomb.foundation.common.part.FilePart; -import org.apache.servicecomb.foundation.vertx.stream.PumpFromPart; -import org.hamcrest.MatcherAssert; -import org.hamcrest.Matchers; -import org.junit.Before; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - -import io.vertx.core.AsyncResult; -import io.vertx.core.Context; -import io.vertx.core.Handler; -import io.vertx.core.MultiMap; -import io.vertx.core.Promise; -import io.vertx.core.Vertx; -import io.vertx.core.buffer.Buffer; -import io.vertx.core.http.HttpServerResponse; -import io.vertx.core.impl.SyncContext; -import io.vertx.core.streams.WriteStream; -import jakarta.servlet.http.Part; -import jakarta.ws.rs.core.HttpHeaders; -import jakarta.ws.rs.core.Response.StatusType; -import mockit.Deencapsulation; -import mockit.Expectations; -import mockit.Mock; -import mockit.MockUp; -import mockit.Mocked; - -public class TestVertxServerResponseToHttpServletResponse { - MultiMap headers = MultiMap.caseInsensitiveMultiMap(); - - HttpStatus httpStatus = new HttpStatus(123, "default"); - - HttpServerResponse serverResponse; - - VertxServerResponseToHttpServletResponse response; - - boolean flushWithBody; - - boolean runOnContextInvoked; - - @Mocked - Vertx vertx; - - @Mocked - Context context; - - boolean chunked; - - @Before - public void setup() { - serverResponse = new MockUp() { - @Mock - HttpServerResponse setStatusCode(int statusCode) { - Deencapsulation.setField(httpStatus, "statusCode", statusCode); - return serverResponse; - } - - @Mock - HttpServerResponse setStatusMessage(String statusMessage) { - Deencapsulation.setField(httpStatus, "reason", statusMessage); - return serverResponse; - } - - @Mock - int getStatusCode() { - return httpStatus.getStatusCode(); - } - - @Mock - String getStatusMessage() { - return httpStatus.getReasonPhrase(); - } - - @Mock - MultiMap headers() { - return headers; - } - - @Mock - HttpServerResponse putHeader(String name, String value) { - headers.set(name, value); - return serverResponse; - } - - @Mock - void end() { - flushWithBody = false; - } - - @Mock - void end(Buffer chunk) { - flushWithBody = true; - } - - @Mock - HttpServerResponse setChunked(boolean chunked) { - TestVertxServerResponseToHttpServletResponse.this.chunked = chunked; - return serverResponse; - } - - @Mock - boolean isChunked() { - return chunked; - } - }.getMockInstance(); - - new Expectations() { - { - Vertx.currentContext(); - result = context; - } - }; - - new MockUp(context) { - @Mock - void runOnContext(Handler action) { - runOnContextInvoked = true; - action.handle(null); - } - - @Mock - void executeBlocking(Handler> blockingCodeHandler, boolean ordered, - Handler> resultHandler) { - SyncContext.syncExecuteBlocking(blockingCodeHandler, resultHandler); - } - - @Mock - Vertx owner() { - return vertx; - } - }; - - response = new VertxServerResponseToHttpServletResponse(serverResponse); - } - - @Test - public void construct_invalid() throws IOException { - new Expectations() { - { - Vertx.currentContext(); - result = null; - } - }; - - NullPointerException exception = Assertions.assertThrows(NullPointerException.class, - () -> new VertxServerResponseToHttpServletResponse(serverResponse)); - Assertions.assertEquals("must run in vertx context.", exception.getMessage()); - } - - @Test - public void setContentType() { - response.setContentType("json"); - Assertions.assertEquals("json", headers.get(HttpHeaders.CONTENT_TYPE)); - } - - @Test - public void getStatusType() { - StatusType status = response.getStatusType(); - - Assertions.assertSame(status, response.getStatusType()); - Assertions.assertEquals(123, httpStatus.getStatusCode()); - Assertions.assertEquals("default", httpStatus.getReasonPhrase()); - } - - @Test - public void addHeader() { - response.addHeader("n1", "v1_1"); - response.addHeader("n1", "v1_2"); - response.addHeader("n2", "v2"); - - Assertions.assertEquals(2, headers.size()); - MatcherAssert.assertThat(headers.getAll("n1"), Matchers.contains("v1_1", "v1_2")); - MatcherAssert.assertThat(headers.getAll("n2"), Matchers.contains("v2")); - } - - @Test - public void setHeader() { - response.setHeader("n1", "v1_1"); - response.setHeader("n1", "v1_2"); - response.setHeader("n2", "v2"); - - Assertions.assertEquals(2, headers.size()); - MatcherAssert.assertThat(headers.getAll("n1"), Matchers.contains("v1_2")); - MatcherAssert.assertThat(headers.getAll("n2"), Matchers.contains("v2")); - } - - @Test - public void getStatus() { - Assertions.assertEquals(123, response.getStatus()); - } - - @Test - public void getContentType() { - headers.set(HttpHeaders.CONTENT_TYPE, "json"); - Assertions.assertEquals("json", response.getContentType()); - } - - @Test - public void getHeader() { - headers.set(HttpHeaders.CONTENT_TYPE, "json"); - Assertions.assertEquals("json", response.getHeader(HttpHeaders.CONTENT_TYPE)); - } - - @Test - public void getHeaders() { - headers.add("h1", "h1_1"); - headers.add("h1", "h1_2"); - - MatcherAssert.assertThat(response.getHeaders("h1"), Matchers.contains("h1_1", "h1_2")); - } - - @Test - public void getHeaderNames() { - headers.add("h1", "h1"); - headers.add("h2", "h2"); - - MatcherAssert.assertThat(response.getHeaderNames(), Matchers.contains("h1", "h2")); - } - - @Test - public void flushBuffer_sameContext() throws IOException { - response.endResponse(); - - Assertions.assertFalse(runOnContextInvoked); - } - - @Test - public void flushBuffer_diffContext() throws IOException { - new Expectations() { - { - Vertx.currentContext(); - result = null; - } - }; - response.endResponse(); - - Assertions.assertTrue(runOnContextInvoked); - } - - @Test - public void internalFlushBufferNoBody() throws IOException { - response.internalFlushBuffer(); - - Assertions.assertFalse(flushWithBody); - } - - @Test - public void internalFlushBufferWithBody() throws IOException { - response.setBodyBuffer(Buffer.buffer()); - response.internalFlushBuffer(); - - Assertions.assertFalse(flushWithBody); - } - - @Test - public void prepareSendPartHeader_update(@Mocked Part part) { - new Expectations() { - { - part.getContentType(); - result = "type"; - part.getSubmittedFileName(); - result = "测 试"; - } - }; - DownloadUtils.prepareDownloadHeader(response, part); - - Assertions.assertTrue(serverResponse.isChunked()); - Assertions.assertEquals("type", response.getHeader(HttpHeaders.CONTENT_TYPE)); - Assertions.assertEquals( - "attachment;filename=%E6%B5%8B%20%20%20%20%20%E8%AF%95;filename*=utf-8''%E6%B5%8B%20%20%20%20%20%E8%AF%95", - response.getHeader(HttpHeaders.CONTENT_DISPOSITION)); - } - - @Test - public void prepareSendPartHeader_notUpdate(@Mocked Part part) { - headers.add(HttpHeaders.CONTENT_LENGTH, "10"); - headers.add(HttpHeaders.CONTENT_TYPE, "type"); - headers.add(HttpHeaders.CONTENT_DISPOSITION, "disposition"); - - DownloadUtils.prepareDownloadHeader(response, part); - - Assertions.assertFalse(serverResponse.isChunked()); - Assertions.assertEquals("type", response.getHeader(HttpHeaders.CONTENT_TYPE)); - Assertions.assertEquals("disposition", response.getHeader(HttpHeaders.CONTENT_DISPOSITION)); - } - - @Test - public void sendPart_openInputStreamFailed(@Mocked Part part) - throws IOException { - IOException ioException = new IOException("forbid open stream"); - new Expectations() { - { - part.getInputStream(); - result = ioException; - } - }; - - CompletableFuture future = response.sendPart(part); - - ExecutionException exception = Assertions.assertThrows(ExecutionException.class, future::get); - Assertions.assertTrue(exception.getCause() instanceof IOException); - } - - @Test - public void sendPart_testPartIsNull(@Mocked Part part) throws InterruptedException, ExecutionException { - CompletableFuture future1 = response.sendPart(null); - Assertions.assertNull(future1.get()); - } - - @Test - public void sendPart_inputStreamBreak(@Mocked Part part, @Mocked InputStream inputStream) - throws IOException { - IOException ioException = new IOException("forbid read"); - new Expectations() { - { - part.getInputStream(); - result = inputStream; - inputStream.read((byte[]) any); - result = ioException; - } - }; - - CompletableFuture future = response.sendPart(part); - - ExecutionException exception = Assertions.assertThrows(ExecutionException.class, future::get); - Assertions.assertTrue(exception.getCause() instanceof IOException); - } - - @Test - public void sendPart_ReadStreamPart(@Mocked ReadStreamPart part) { - CompletableFuture future = new CompletableFuture<>(); - new MockUp() { - @Mock - CompletableFuture toWriteStream(WriteStream writeStream, Handler throwableHandler) { - return future; - } - }; - - Assertions.assertSame(future, response.sendPart(part)); - } - - @Test - public void sendPart_succ(@Mocked Part part, @Mocked InputStream inputStream) - throws IOException, InterruptedException, ExecutionException { - new Expectations() { - { - part.getInputStream(); - result = inputStream; - inputStream.read((byte[]) any); - result = -1; - } - }; - - CompletableFuture future = response.sendPart(part); - - Assertions.assertNull(future.get()); - } - - @Test - public void clearPartResource_deleteFile() throws IOException { - File file = new File("target", UUID.randomUUID() + ".txt"); - FileUtils.write(file, "content", StandardCharsets.UTF_8); - FilePart part = new FilePart(null, file).setDeleteAfterFinished(true); - - Assertions.assertTrue(file.exists()); - DownloadUtils.clearPartResource(part); - Assertions.assertFalse(file.exists()); - } - - @Test - public void clearPartResource_notDeleteFile() throws IOException { - File file = new File("target", UUID.randomUUID() + ".txt"); - FileUtils.write(file, "content", StandardCharsets.UTF_8); - FilePart part = new FilePart(null, file); - - Assertions.assertTrue(file.exists()); - DownloadUtils.clearPartResource(part); - Assertions.assertTrue(file.exists()); - - file.delete(); - } -} diff --git a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultVertxMetricsFactory.java b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultVertxMetricsFactory.java index 1ae56ebee4a..ccc67374c82 100644 --- a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultVertxMetricsFactory.java +++ b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultVertxMetricsFactory.java @@ -29,14 +29,12 @@ public class TestDefaultVertxMetricsFactory { DefaultVertxMetricsFactory factory = new DefaultVertxMetricsFactory(); - @SuppressWarnings("deprecation") @Test public void metrics() { MetricsOptions metricsOptions = factory.newOptions(); options.setMetricsOptions(metricsOptions); VertxMetrics vertxMetrics = factory.metrics(options); - Assertions.assertSame(factory, metricsOptions.getFactory()); Assertions.assertTrue(metricsOptions.isEnabled()); Assertions.assertSame(factory.getVertxMetrics(), vertxMetrics); diff --git a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/server/TestTcpServer.java b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/server/TestTcpServer.java deleted file mode 100644 index 489a21d8a1e..00000000000 --- a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/server/TestTcpServer.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.servicecomb.foundation.vertx.server; - -import static org.mockito.ArgumentMatchers.any; - -import java.net.InetSocketAddress; - -import org.apache.servicecomb.foundation.common.LegacyPropertyFactory; -import org.apache.servicecomb.foundation.common.net.URIEndpointObject; -import org.apache.servicecomb.foundation.vertx.AsyncResultCallback; -import org.apache.servicecomb.foundation.vertx.metrics.DefaultTcpServerMetrics; -import org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultServerEndpointMetric; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.mockito.stubbing.Answer; -import org.springframework.core.env.Environment; - -import io.vertx.core.Handler; -import io.vertx.core.Vertx; -import io.vertx.core.net.NetServer; -import io.vertx.core.net.NetSocket; -import io.vertx.core.net.SocketAddress; -import io.vertx.core.net.impl.NetSocketImpl; - -public class TestTcpServer { - static class TcpServerForTest extends TcpServer { - public TcpServerForTest(URIEndpointObject endpointObject) { - super(endpointObject); - } - - @Override - protected TcpServerConnection createTcpServerConnection() { - return new TcpServerConnection() { - @Override - public void init(NetSocket netSocket) { - super.init(netSocket); - } - }; - } - } - - protected Environment environment; - - @BeforeEach - public void setup() { - environment = Mockito.mock(Environment.class); - LegacyPropertyFactory.setEnvironment(environment); - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - @Test - public void testTcpServerNonSSL() { - Vertx vertx = Mockito.mock(Vertx.class); - AsyncResultCallback callback = Mockito.mock(AsyncResultCallback.class); - NetServer netServer = Mockito.mock(NetServer.class); - Mockito.when(vertx.createNetServer()).thenReturn(netServer); - - URIEndpointObject endpointObject = new URIEndpointObject("highway://127.0.0.1:6663"); - TcpServer server = new TcpServerForTest(endpointObject); - // assert done in Expectations - server.init(vertx, "", callback); - } - - Handler connectHandler; - - boolean netSocketClosed; - - @SuppressWarnings({"rawtypes", "unchecked"}) - @Test - public void testConnectionLimit() { - Vertx vertx = Mockito.mock(Vertx.class); - AsyncResultCallback callback = Mockito.mock(AsyncResultCallback.class); - NetServer netServer = Mockito.mock(NetServer.class); - NetSocketImpl netSocket = Mockito.mock(NetSocketImpl.class); - Mockito.when(vertx.createNetServer(any())).thenReturn(netServer); - - DefaultServerEndpointMetric endpointMetric = new DefaultServerEndpointMetric(null); - DefaultTcpServerMetrics tcpServerMetrics = new DefaultTcpServerMetrics(endpointMetric); - - Mockito.doAnswer((Answer) invocationOnMock -> { - connectHandler = invocationOnMock.getArgument(0); - return netServer; - }).when(netServer).connectHandler(any()); - - Mockito.doAnswer((Answer) invocationOnMock -> { - netSocketClosed = true; - return null; - }).when(netSocket).close(); - Mockito.when(netSocket.metrics()).thenReturn(tcpServerMetrics); - SocketAddress socketAddress = Mockito.mock(SocketAddress.class); - Mockito.when(netSocket.remoteAddress()).thenReturn(socketAddress); - Mockito.when(socketAddress.toString()).thenReturn("127.0.0.1:6663"); - - URIEndpointObject endpointObject = new URIEndpointObject("highway://127.0.0.1:6663?sslEnabled=true"); - TcpServer server = new TcpServerForTest(endpointObject) { - @Override - protected int getConnectionLimit() { - return 2; - } - }; - // assert done in Expectations - server.init(vertx, "", callback); - - // no problem - endpointMetric.onConnect(); - endpointMetric.onConnect(); - connectHandler.handle(netSocket); - - // reject - endpointMetric.onConnect(); - connectHandler.handle(netSocket); - Assertions.assertTrue(netSocketClosed); - Assertions.assertEquals(1, endpointMetric.getRejectByConnectionLimitCount()); - } -} diff --git a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/stream/TestPumpFromPart.java b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/stream/TestPumpFromPart.java deleted file mode 100644 index b32e790e00b..00000000000 --- a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/stream/TestPumpFromPart.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.servicecomb.foundation.vertx.stream; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.concurrent.ExecutionException; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.servicecomb.foundation.common.part.InputStreamPart; -import org.apache.servicecomb.foundation.vertx.stream.InputStreamToReadStream.ReadResult; -import org.hamcrest.MatcherAssert; -import org.hamcrest.Matchers; -import org.junit.Before; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; - -import io.vertx.core.Context; -import io.vertx.core.Promise; -import io.vertx.core.Vertx; -import io.vertx.core.impl.SyncContext; -import io.vertx.core.impl.VertxInternal; -import jakarta.servlet.http.Part; -import mockit.Expectations; -import mockit.Mock; -import mockit.MockUp; - -public class TestPumpFromPart { - static Vertx vertx = Vertx.vertx(); - - String src = RandomStringUtils.random(100, true, true); - - boolean inputStreamClosed; - - InputStream inputStream = new ByteArrayInputStream(src.getBytes()) { - @Override - public void close() throws IOException { - super.close(); - inputStreamClosed = true; - } - }; - - Part part; - - boolean outputStreamClosed; - - BufferOutputStream outputStream; - - IOException error = new IOException(); - - SyncContext context = new SyncContext(); - - @Before - public void setup() throws IOException { - context.setOwner((VertxInternal) vertx); - } - - private void run(Context context, boolean closeOutput) throws Throwable { - inputStream.reset(); - part = new InputStreamPart("name", inputStream); - - outputStream = new BufferOutputStream() { - @Override - public void close() { - super.close(); - outputStreamClosed = true; - } - }; - - new PumpFromPart(context, part).toOutputStream(outputStream, closeOutput).get(); - } - - public void do_pump_succ(Context context) throws Throwable { - run(context, true); - - Assertions.assertEquals(src, outputStream.getBuffer().toString()); - Assertions.assertTrue(inputStreamClosed); - Assertions.assertTrue(outputStreamClosed); - } - - @Test - public void pump_succ() throws Throwable { - do_pump_succ(null); - do_pump_succ(context); - } - - public void do_pump_outputNotClose(Context context) throws Throwable { - run(context, false); - - Assertions.assertEquals(src, outputStream.getBuffer().toString()); - Assertions.assertFalse(outputStreamClosed); - } - - @Test - public void pump_outputNotClose() throws Throwable { - do_pump_outputNotClose(null); - do_pump_outputNotClose(context); - } - - public void pump_error(Context context) { - try { - run(context, true); - Assertions.fail("must throw exception"); - } catch (Throwable e) { - MatcherAssert.assertThat(e, Matchers.instanceOf(ExecutionException.class)); - MatcherAssert.assertThat(e.getCause(), Matchers.sameInstance(error)); - } - - Assertions.assertTrue(inputStreamClosed); - Assertions.assertTrue(outputStreamClosed); - } - - @Test - public void pump_read_error() throws IOException { - new MockUp() { - @Mock - void readInWorker(Promise future) { - future.fail(error); - } - }; - new Expectations(IOUtils.class) { - { - IOUtils.copyLarge((InputStream) any, (OutputStream) any); - result = error; - } - }; - - pump_error(null); - Assertions.assertTrue(inputStreamClosed); - Assertions.assertTrue(outputStreamClosed); - - inputStreamClosed = false; - outputStreamClosed = false; - pump_error(context); - Assertions.assertTrue(inputStreamClosed); - Assertions.assertTrue(outputStreamClosed); - } - - @Test - public void pump_write_error() throws IOException { - new MockUp() { - @Mock - void write(byte[] b) throws IOException { - throw error; - } - }; - new Expectations(IOUtils.class) { - { - IOUtils.copyLarge((InputStream) any, (OutputStream) any); - result = error; - } - }; - - pump_error(null); - Assertions.assertTrue(inputStreamClosed); - Assertions.assertTrue(outputStreamClosed); - - inputStreamClosed = false; - outputStreamClosed = false; - pump_error(context); - Assertions.assertTrue(inputStreamClosed); - Assertions.assertTrue(outputStreamClosed); - } -} diff --git a/foundations/pom.xml b/foundations/pom.xml index 9b0ff42a1a6..7b3f55d334a 100644 --- a/foundations/pom.xml +++ b/foundations/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default foundations diff --git a/governance/pom.xml b/governance/pom.xml index 7c2453939da..3f78c36ade5 100644 --- a/governance/pom.xml +++ b/governance/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default 4.0.0 diff --git a/governance/src/main/java/org/apache/servicecomb/governance/marker/operator/CompareOperator.java b/governance/src/main/java/org/apache/servicecomb/governance/marker/operator/CompareOperator.java index 5379bf8c24c..5b73b9aa939 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/marker/operator/CompareOperator.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/marker/operator/CompareOperator.java @@ -38,7 +38,7 @@ public String name() { } /** - * 支持 > < = >= <= ! 后面加数字 + * 支持 {@code > < = >= <= !} 后面加数字 * * @param targetStr * @param patternStr diff --git a/governance/src/main/java/org/apache/servicecomb/router/distribute/AbstractRouterDistributor.java b/governance/src/main/java/org/apache/servicecomb/router/distribute/AbstractRouterDistributor.java index c34ad909ae8..d3905dfb133 100644 --- a/governance/src/main/java/org/apache/servicecomb/router/distribute/AbstractRouterDistributor.java +++ b/governance/src/main/java/org/apache/servicecomb/router/distribute/AbstractRouterDistributor.java @@ -79,14 +79,14 @@ public List distribute(String targetServiceName, List list, unSetTagInstances, fallbackVersionServerMap); // weight calculation to obtain the next tags instance - TagItem targetTag = getFiltedServerTagItem(invokeRule, targetServiceName); + TagItem targetTag = getFilteredServerTagItem(invokeRule, targetServiceName); if (targetTag != null && versionServerMap.containsKey(targetTag)) { return versionServerMap.get(targetTag); } if (!fallbackVersionServerMap.isEmpty()) { // weight calculation to obtain the next fallback tags instance - TagItem fallbackTargetTag = getFallbackFiltedServerTagItem(invokeRule, targetServiceName); + TagItem fallbackTargetTag = getFallbackFilteredServerTagItem(invokeRule, targetServiceName); if (fallbackTargetTag != null && fallbackVersionServerMap.containsKey(fallbackTargetTag)) { return fallbackVersionServerMap.get(fallbackTargetTag); } @@ -113,12 +113,12 @@ public void init(Function getVersion, this.getProperties = getProperties; } - public TagItem getFiltedServerTagItem(PolicyRuleItem rule, String targetServiceName) { + public TagItem getFilteredServerTagItem(PolicyRuleItem rule, String targetServiceName) { return routerRuleCache.getServiceInfoCacheMap().get(targetServiceName) .getNextInvokeVersion(rule); } - public TagItem getFallbackFiltedServerTagItem(PolicyRuleItem rule, String targetServiceName) { + public TagItem getFallbackFilteredServerTagItem(PolicyRuleItem rule, String targetServiceName) { return routerRuleCache.getServiceInfoCacheMap().get(targetServiceName) .getFallbackNextInvokeVersion(rule); } diff --git a/governance/src/main/java/org/apache/servicecomb/router/distribute/RouterDistributor.java b/governance/src/main/java/org/apache/servicecomb/router/distribute/RouterDistributor.java index fa9af8fd16f..5f5babdec34 100644 --- a/governance/src/main/java/org/apache/servicecomb/router/distribute/RouterDistributor.java +++ b/governance/src/main/java/org/apache/servicecomb/router/distribute/RouterDistributor.java @@ -23,8 +23,8 @@ import org.apache.servicecomb.router.model.PolicyRuleItem; /** - * @Author GuoYl123 - * @Date 2019/10/17 + * @author GuoYl123 + * @since 2019/10/17 **/ public interface RouterDistributor { diff --git a/governance/src/main/java/org/apache/servicecomb/router/exception/RouterIllegalParamException.java b/governance/src/main/java/org/apache/servicecomb/router/exception/RouterIllegalParamException.java index 61fda32c8e4..9647a853ea8 100644 --- a/governance/src/main/java/org/apache/servicecomb/router/exception/RouterIllegalParamException.java +++ b/governance/src/main/java/org/apache/servicecomb/router/exception/RouterIllegalParamException.java @@ -17,8 +17,8 @@ package org.apache.servicecomb.router.exception; /** - * @Author GuoYl123 - * @Date 2019/11/4 + * @author GuoYl123 + * @since 2019/11/4 **/ public class RouterIllegalParamException extends RuntimeException { diff --git a/governance/src/main/java/org/apache/servicecomb/router/model/HeaderRule.java b/governance/src/main/java/org/apache/servicecomb/router/model/HeaderRule.java index 931fcee2273..7a8afeda77f 100644 --- a/governance/src/main/java/org/apache/servicecomb/router/model/HeaderRule.java +++ b/governance/src/main/java/org/apache/servicecomb/router/model/HeaderRule.java @@ -21,8 +21,8 @@ import org.slf4j.LoggerFactory; /** - * @Author GuoYl123 - * @Date 2019/10/17 + * @author GuoYl123 + * @since 2019/10/17 **/ public class HeaderRule { diff --git a/governance/src/main/java/org/apache/servicecomb/router/model/PolicyRuleItem.java b/governance/src/main/java/org/apache/servicecomb/router/model/PolicyRuleItem.java index fa2d285ef3d..0700a2618d8 100644 --- a/governance/src/main/java/org/apache/servicecomb/router/model/PolicyRuleItem.java +++ b/governance/src/main/java/org/apache/servicecomb/router/model/PolicyRuleItem.java @@ -25,8 +25,8 @@ import org.springframework.util.CollectionUtils; /** - * @Author GuoYl123 - * @Date 2019/10/17 + * @author GuoYl123 + * @since 2019/10/17 **/ public class PolicyRuleItem implements Comparable { diff --git a/governance/src/main/java/org/apache/servicecomb/router/model/RouteItem.java b/governance/src/main/java/org/apache/servicecomb/router/model/RouteItem.java index f2017a923e0..5f1d6e9f8df 100644 --- a/governance/src/main/java/org/apache/servicecomb/router/model/RouteItem.java +++ b/governance/src/main/java/org/apache/servicecomb/router/model/RouteItem.java @@ -19,8 +19,8 @@ import java.util.Map; /** - * @Author GuoYl123 - * @Date 2019/10/17 + * @author GuoYl123 + * @since 2019/10/17 **/ public class RouteItem implements Comparable { diff --git a/governance/src/main/java/org/apache/servicecomb/router/model/ServiceInfoCache.java b/governance/src/main/java/org/apache/servicecomb/router/model/ServiceInfoCache.java index 67640320636..232f1da6338 100644 --- a/governance/src/main/java/org/apache/servicecomb/router/model/ServiceInfoCache.java +++ b/governance/src/main/java/org/apache/servicecomb/router/model/ServiceInfoCache.java @@ -22,8 +22,8 @@ import org.springframework.util.CollectionUtils; /** - * @Author GuoYl123 - * @Date 2019/10/17 + * @author GuoYl123 + * @since 2019/10/17 **/ public class ServiceInfoCache { private final List allrule; diff --git a/governance/src/main/java/org/apache/servicecomb/router/model/TagItem.java b/governance/src/main/java/org/apache/servicecomb/router/model/TagItem.java index 0fc610df769..a7a20fab7ea 100644 --- a/governance/src/main/java/org/apache/servicecomb/router/model/TagItem.java +++ b/governance/src/main/java/org/apache/servicecomb/router/model/TagItem.java @@ -21,8 +21,8 @@ import java.util.Objects; /** - * @Author GuoYl123 - * @Date 2019/10/17 + * @author GuoYl123 + * @since 2019/10/17 **/ public class TagItem { diff --git a/handlers/handler-fault-injection/pom.xml b/handlers/handler-fault-injection/pom.xml index 1194f36f94c..825c63c2270 100755 --- a/handlers/handler-fault-injection/pom.xml +++ b/handlers/handler-fault-injection/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb handlers - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT handler-fault-injection Java Chassis::Handlers::Fault Injection diff --git a/handlers/handler-flowcontrol-qps/pom.xml b/handlers/handler-flowcontrol-qps/pom.xml index baa37871767..eb5d63a0993 100644 --- a/handlers/handler-flowcontrol-qps/pom.xml +++ b/handlers/handler-flowcontrol-qps/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb handlers - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT handler-flowcontrol-qps Java Chassis::Handlers::Flow Control QPS diff --git a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestQpsStrategy.java b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestQpsStrategy.java index 23c228fab2e..f34b6c5a261 100644 --- a/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestQpsStrategy.java +++ b/handlers/handler-flowcontrol-qps/src/test/java/org/apache/servicecomb/qps/TestQpsStrategy.java @@ -24,8 +24,8 @@ import org.junit.jupiter.api.Test; /** - * @Author GuoYl123 - * @Date 2020/7/16 + * @author GuoYl123 + * @since 2020/7/16 **/ public class TestQpsStrategy { diff --git a/handlers/handler-governance/pom.xml b/handlers/handler-governance/pom.xml index 7d072af7e59..7db533e562e 100644 --- a/handlers/handler-governance/pom.xml +++ b/handlers/handler-governance/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb handlers - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT handler-governance diff --git a/handlers/handler-loadbalance/pom.xml b/handlers/handler-loadbalance/pom.xml index 39b3bdad749..0fd42dce838 100644 --- a/handlers/handler-loadbalance/pom.xml +++ b/handlers/handler-loadbalance/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb handlers - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT handler-loadbalance diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java index 5f766e8855e..87a527c9aff 100644 --- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java +++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/Configuration.java @@ -25,7 +25,6 @@ /** * configuration items - * */ public final class Configuration { //// 2.1 configuration items diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java index 5f8d26c0ff8..318b45f3839 100644 --- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java +++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/RandomRuleExt.java @@ -31,7 +31,7 @@ public ServiceCombServer choose(List servers, Invocation invo if (servers.isEmpty()) { return null; } - int index = Math.abs(ThreadLocalRandom.current().nextInt()) % servers.size(); + int index = ThreadLocalRandom.current().nextInt(servers.size()); return servers.get(index); } } diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/SessionStickinessRule.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/SessionStickinessRule.java index c3c250b9e48..37d94bc0fa1 100644 --- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/SessionStickinessRule.java +++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/SessionStickinessRule.java @@ -40,7 +40,7 @@ public class SessionStickinessRule implements RuleExt { private volatile ServiceCombServer lastServer = null; - private long lastAccessedTime = 0; + private volatile long lastAccessedTime = 0; private volatile boolean errorThresholdMet = false; diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/InstancePropertyDiscoveryFilter.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/InstancePropertyDiscoveryFilter.java index d3811d3a725..2b4c3eb6b20 100644 --- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/InstancePropertyDiscoveryFilter.java +++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/InstancePropertyDiscoveryFilter.java @@ -30,11 +30,14 @@ import org.apache.servicecomb.registry.discovery.StatefulDiscoveryInstance; /** - * Instance property based filter + * Instance property based filter */ public class InstancePropertyDiscoveryFilter extends AbstractDiscoveryFilter { + private static final String MATCHED = "matched"; + public static final String SERVICECOMB_LOADBALANCE_FILTER_INSTANCE_PROPERTY_ENABLED = "servicecomb.loadbalance.filter.instanceProperty.enabled"; + @Override public int getOrder() { return 400; @@ -42,8 +45,13 @@ public int getOrder() { @Override public boolean enabled() { - return environment.getProperty("servicecomb.loadbalance.filter.instanceProperty.enabled", - boolean.class, true); + + if (enabled == null) { + enabled = dynamicProperties.getBooleanProperty(SERVICECOMB_LOADBALANCE_FILTER_INSTANCE_PROPERTY_ENABLED, + value -> enabled = value, + true); + } + return enabled; } @Override diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/PriorityInstancePropertyDiscoveryFilter.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/PriorityInstancePropertyDiscoveryFilter.java index 7dbe070237d..d890b7ea229 100644 --- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/PriorityInstancePropertyDiscoveryFilter.java +++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/PriorityInstancePropertyDiscoveryFilter.java @@ -47,6 +47,8 @@ public class PriorityInstancePropertyDiscoveryFilter extends AbstractDiscoveryFi private static final String ALL_INSTANCE = "allInstance"; + public static final String SERVICECOMB_LOADBALANCE_FILTER_PRIORITY_INSTANCE_PROPERTY_KEY = "servicecomb.loadbalance.filter.priorityInstanceProperty.key"; + private String propertyKey; private Environment environment; @@ -58,8 +60,10 @@ public void setEnvironment(Environment environment) { @Override protected void init(DiscoveryContext context, DiscoveryTreeNode parent) { - propertyKey = environment.getProperty("servicecomb.loadbalance.filter.priorityInstanceProperty.key", - String.class, "environment"); + + propertyKey = dynamicProperties.getStringProperty(SERVICECOMB_LOADBALANCE_FILTER_PRIORITY_INSTANCE_PROPERTY_KEY, + value -> propertyKey = value, + "environment"); // group all instance by property List instances = parent.data(); @@ -115,8 +119,13 @@ protected String findChildName(DiscoveryContext context, DiscoveryTreeNode paren @Override public boolean enabled() { - return environment.getProperty("servicecomb.loadbalance.filter.priorityInstanceProperty.enabled", - boolean.class, false); + + if (enabled == null) { + enabled = dynamicProperties.getBooleanProperty("servicecomb.loadbalance.filter.priorityInstanceProperty.enabled", + value -> enabled = value, + false); + } + return enabled; } @Override @@ -136,7 +145,7 @@ static class PriorityInstanceProperty { /** * Constructor * - * @param key property key + * @param key property key * @param value property value */ public PriorityInstanceProperty(@NotNull String key, String value) { @@ -153,7 +162,7 @@ public PriorityInstanceProperty(@NotNull String key, String value) { /** * Constructor * - * @param key property key + * @param key property key * @param microserviceInstance instance */ public PriorityInstanceProperty(@NotNull String key, @NotNull StatefulDiscoveryInstance microserviceInstance) { diff --git a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/ZoneAwareDiscoveryFilter.java b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/ZoneAwareDiscoveryFilter.java index b39aefe8f89..0e521397f13 100644 --- a/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/ZoneAwareDiscoveryFilter.java +++ b/handlers/handler-loadbalance/src/main/java/org/apache/servicecomb/loadbalance/filter/ZoneAwareDiscoveryFilter.java @@ -42,6 +42,11 @@ public class ZoneAwareDiscoveryFilter extends AbstractGroupDiscoveryFilter { private DataCenterProperties dataCenterProperties; + private Integer ratio; + + private Integer ratioCeiling; + + @Autowired @SuppressWarnings("unused") public void setDataCenterProperties(DataCenterProperties dataCenterProperties) { @@ -55,18 +60,33 @@ public int getOrder() { @Override public boolean enabled() { - return environment.getProperty(CONFIG_ENABLED, - Boolean.class, true); + + if (enabled == null) { + enabled = dynamicProperties.getBooleanProperty(CONFIG_ENABLED, + value -> enabled = value, + true); + } + return enabled; } private int getRatio() { - return environment.getProperty(CONFIG_RATIO, - int.class, 30); + + if (ratio == null) { + ratio = dynamicProperties.getIntProperty(CONFIG_RATIO, + value -> ratio = value, + 30); + } + return ratio; } private int getRatioCeiling(int defaultValue) { - return environment.getProperty(CONFIG_RATIO_CEILING, - int.class, defaultValue); + + if (ratioCeiling == null) { + ratioCeiling = dynamicProperties.getIntProperty(CONFIG_RATIO_CEILING, + value -> ratioCeiling = value, + defaultValue); + } + return ratioCeiling; } @Override diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceFilter2.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceFilter2.java index 25858a98092..4c2fb5f5b45 100644 --- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceFilter2.java +++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceFilter2.java @@ -25,6 +25,7 @@ import java.util.List; import org.apache.servicecomb.config.DataCenterProperties; +import org.apache.servicecomb.config.DynamicProperties; import org.apache.servicecomb.core.Invocation; import org.apache.servicecomb.core.NonSwaggerInvocation; import org.apache.servicecomb.core.SCBEngine; @@ -35,6 +36,7 @@ import org.apache.servicecomb.core.definition.SchemaMeta; import org.apache.servicecomb.core.provider.consumer.ReferenceConfig; import org.apache.servicecomb.core.transport.TransportManager; +import org.apache.servicecomb.foundation.common.LegacyPropertyFactory; import org.apache.servicecomb.loadbalance.filter.ServerDiscoveryFilter; import org.apache.servicecomb.loadbalance.filter.ZoneAwareDiscoveryFilter; import org.apache.servicecomb.registry.DiscoveryManager; @@ -54,18 +56,30 @@ import io.swagger.v3.oas.models.Operation; public class TestLoadBalanceFilter2 { + DynamicProperties dynamicProperties = Mockito.mock(DynamicProperties.class); + Environment environment = Mockito.mock(Environment.class); @BeforeEach public void setUp() { + Mockito.when(environment.getProperty("servicecomb.loadbalance.userDefinedEndpoint.enabled", boolean.class, false)).thenReturn(false); - Mockito.when(environment.getProperty("servicecomb.loadbalance.filter.zoneaware.enabled", - Boolean.class, true)).thenReturn(true); - Mockito.when(environment.getProperty("servicecomb.loadbalance.filter.zoneaware.ratio", - int.class, 30)).thenReturn(0); - Mockito.when(environment.getProperty("servicecomb.loadbalance.filter.zoneaware.ratioCeiling", - int.class, 100)).thenReturn(100); + + Mockito.when(dynamicProperties.getBooleanProperty(Mockito.eq("servicecomb.loadbalance.filter.zoneaware.enabled"), + Mockito.any(), + Mockito.eq(true))) + .thenReturn(true); + Mockito.when(dynamicProperties.getIntProperty(Mockito.eq("servicecomb.loadbalance.filter.zoneaware.ratio"), + Mockito.any(), + Mockito.eq(30))) + .thenReturn(0); + Mockito.when(dynamicProperties.getIntProperty(Mockito.eq("servicecomb.loadbalance.filter.zoneaware.ratioCeiling"), + Mockito.any(), + Mockito.eq(100))) + .thenReturn(100); + + LegacyPropertyFactory.setEnvironment(environment); } @Test @@ -148,7 +162,7 @@ public void testZoneAwareFilterWorks() { .thenReturn(parent); DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager); ZoneAwareDiscoveryFilter zoneAwareDiscoveryFilter = new ZoneAwareDiscoveryFilter(); - zoneAwareDiscoveryFilter.setEnvironment(environment); + zoneAwareDiscoveryFilter.setDynamicProperties(dynamicProperties); zoneAwareDiscoveryFilter.setDataCenterProperties(myself); ServerDiscoveryFilter serverDiscoveryFilter = new ServerDiscoveryFilter(); serverDiscoveryFilter.setScbEngine(scbEngine); @@ -239,7 +253,7 @@ public void testIsolationEventWithEndpoint() { .thenReturn(parent); DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager); ZoneAwareDiscoveryFilter zoneAwareDiscoveryFilter = new ZoneAwareDiscoveryFilter(); - zoneAwareDiscoveryFilter.setEnvironment(environment); + zoneAwareDiscoveryFilter.setDynamicProperties(dynamicProperties); zoneAwareDiscoveryFilter.setDataCenterProperties(myself); ServerDiscoveryFilter serverDiscoveryFilter = new ServerDiscoveryFilter(); serverDiscoveryFilter.setScbEngine(scbEngine); @@ -339,7 +353,7 @@ public void testZoneAwareFilterWorksEmptyInstanceProtectionEnabled() { .thenReturn(parent); DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager); ZoneAwareDiscoveryFilter zoneAwareDiscoveryFilter = new ZoneAwareDiscoveryFilter(); - zoneAwareDiscoveryFilter.setEnvironment(environment); + zoneAwareDiscoveryFilter.setDynamicProperties(dynamicProperties); zoneAwareDiscoveryFilter.setDataCenterProperties(myself); ServerDiscoveryFilter serverDiscoveryFilter = new ServerDiscoveryFilter(); serverDiscoveryFilter.setScbEngine(scbEngine); @@ -437,7 +451,7 @@ public void testZoneAwareFilterUsingMockedInvocationWorks() { .thenReturn(parent); DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager); ZoneAwareDiscoveryFilter zoneAwareDiscoveryFilter = new ZoneAwareDiscoveryFilter(); - zoneAwareDiscoveryFilter.setEnvironment(environment); + zoneAwareDiscoveryFilter.setDynamicProperties(dynamicProperties); zoneAwareDiscoveryFilter.setDataCenterProperties(myself); ServerDiscoveryFilter serverDiscoveryFilter = new ServerDiscoveryFilter(); serverDiscoveryFilter.setScbEngine(scbEngine); @@ -534,7 +548,7 @@ public void testStatusFilterUsingMockedInvocationWorks() { .thenReturn(parent); DiscoveryTree discoveryTree = new DiscoveryTree(discoveryManager); ZoneAwareDiscoveryFilter zoneAwareDiscoveryFilter = new ZoneAwareDiscoveryFilter(); - zoneAwareDiscoveryFilter.setEnvironment(environment); + zoneAwareDiscoveryFilter.setDynamicProperties(dynamicProperties); zoneAwareDiscoveryFilter.setDataCenterProperties(myself); ServerDiscoveryFilter serverDiscoveryFilter = new ServerDiscoveryFilter(); serverDiscoveryFilter.setScbEngine(scbEngine); diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/PriorityInstancePropertyDiscoveryFilterTest.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/PriorityInstancePropertyDiscoveryFilterTest.java index 23f7c92f636..7c78388dcdc 100644 --- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/PriorityInstancePropertyDiscoveryFilterTest.java +++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/PriorityInstancePropertyDiscoveryFilterTest.java @@ -27,6 +27,7 @@ import java.util.Set; import java.util.stream.Collectors; +import org.apache.servicecomb.config.DynamicProperties; import org.apache.servicecomb.core.Invocation; import org.apache.servicecomb.registry.api.DiscoveryInstance; import org.apache.servicecomb.registry.discovery.DiscoveryContext; @@ -59,6 +60,8 @@ public class PriorityInstancePropertyDiscoveryFilterTest { EnumerablePropertySource propertySource; + DynamicProperties dynamicProperties = Mockito.mock(DynamicProperties.class); + @Before public void setUp() { propertySource = Mockito.mock(EnumerablePropertySource.class); @@ -71,8 +74,10 @@ public void setUp() { filter = new PriorityInstancePropertyDiscoveryFilter(); filter.setEnvironment(environment); - Mockito.when(environment.getProperty("servicecomb.loadbalance.filter.priorityInstanceProperty.key", - String.class, "environment")).thenReturn("environment"); + filter.setDynamicProperties(dynamicProperties); + Mockito.when(dynamicProperties.getStringProperty(Mockito.eq("servicecomb.loadbalance.filter.priorityInstanceProperty.key"), + Mockito.any(), + Mockito.eq("environment"))).thenReturn("environment"); instances = new ArrayList<>(); filter.setEnvironment(environment); DiscoveryInstance discoveryInstance1 = Mockito.mock(DiscoveryInstance.class); diff --git a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestZoneAwareDiscoveryFilter.java b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestZoneAwareDiscoveryFilter.java index 13a5f6da952..05b6d5432ca 100644 --- a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestZoneAwareDiscoveryFilter.java +++ b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/filter/TestZoneAwareDiscoveryFilter.java @@ -21,6 +21,7 @@ import java.util.List; import org.apache.servicecomb.config.DataCenterProperties; +import org.apache.servicecomb.config.DynamicProperties; import org.apache.servicecomb.registry.api.DataCenterInfo; import org.apache.servicecomb.registry.api.DiscoveryInstance; import org.apache.servicecomb.registry.discovery.DiscoveryContext; @@ -30,26 +31,33 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import org.springframework.core.env.Environment; public class TestZoneAwareDiscoveryFilter { - Environment environment = Mockito.mock(Environment.class); + DynamicProperties dynamicProperties = Mockito.mock(DynamicProperties.class); @BeforeEach public void setUp() { - Mockito.when(environment.getProperty("servicecomb.loadbalance.filter.zoneaware.enabled", - Boolean.class, true)).thenReturn(true); + + Mockito.when(dynamicProperties.getBooleanProperty(Mockito.eq("servicecomb.loadbalance.filter.zoneaware.enabled"), + Mockito.any(), + Mockito.eq(true))) + .thenReturn(true); } @Test public void test_not_enough_instance() { - Mockito.when(environment.getProperty("servicecomb.loadbalance.filter.zoneaware.ratio", - int.class, 30)).thenReturn(50); - Mockito.when(environment.getProperty("servicecomb.loadbalance.filter.zoneaware.ratioCeiling", - int.class, 50)).thenReturn(70); + + Mockito.when(dynamicProperties.getIntProperty(Mockito.eq("servicecomb.loadbalance.filter.zoneaware.ratio"), + Mockito.any(), + Mockito.eq(30))) + .thenReturn(50); + Mockito.when(dynamicProperties.getIntProperty(Mockito.eq("servicecomb.loadbalance.filter.zoneaware.ratioCeiling"), + Mockito.any(), + Mockito.eq(50))) + .thenReturn(70); ZoneAwareDiscoveryFilter filter = new ZoneAwareDiscoveryFilter(); - filter.setEnvironment(environment); + filter.setDynamicProperties(dynamicProperties); // set up data DataCenterProperties myself = new DataCenterProperties(); @@ -113,13 +121,18 @@ public void test_not_enough_instance() { @Test public void test_not_enough_instance_both_ceiling_floor() { - Mockito.when(environment.getProperty("servicecomb.loadbalance.filter.zoneaware.ratio", - int.class, 30)).thenReturn(40); - Mockito.when(environment.getProperty("servicecomb.loadbalance.filter.zoneaware.ratioCeiling", - int.class, 60)).thenReturn(60); + + Mockito.when(dynamicProperties.getIntProperty(Mockito.eq("servicecomb.loadbalance.filter.zoneaware.ratio"), + Mockito.any(), + Mockito.eq(30))) + .thenReturn(40); + Mockito.when(dynamicProperties.getIntProperty(Mockito.eq("servicecomb.loadbalance.filter.zoneaware.ratioCeiling"), + Mockito.any(), + Mockito.eq(60))) + .thenReturn(60); ZoneAwareDiscoveryFilter filter = new ZoneAwareDiscoveryFilter(); - filter.setEnvironment(environment); + filter.setDynamicProperties(dynamicProperties); // set up data DataCenterProperties myself = new DataCenterProperties(); diff --git a/handlers/handler-publickey-auth/pom.xml b/handlers/handler-publickey-auth/pom.xml index 8e1d7e3e8bf..9f13b26f232 100644 --- a/handlers/handler-publickey-auth/pom.xml +++ b/handlers/handler-publickey-auth/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb handlers - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT handler-publickey-auth diff --git a/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/ProviderAuthFilter.java b/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/ProviderAuthFilter.java index 02b1108a545..f525ae88cf8 100644 --- a/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/ProviderAuthFilter.java +++ b/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/ProviderAuthFilter.java @@ -24,6 +24,7 @@ import org.apache.servicecomb.core.filter.Filter; import org.apache.servicecomb.core.filter.FilterNode; import org.apache.servicecomb.core.filter.ProviderFilter; +import org.apache.servicecomb.swagger.SwaggerUtils; import org.apache.servicecomb.swagger.invocation.Response; import org.apache.servicecomb.swagger.invocation.exception.InvocationException; import org.springframework.beans.factory.annotation.Autowired; @@ -54,7 +55,9 @@ public String getName() { @Override public CompletableFuture onFilter(Invocation invocation, FilterNode nextNode) { - if (PathCheckUtils.isNotRequiredAuth(invocation.getOperationMeta().getOperationPath(), env)) { + String requestFullPath = SwaggerUtils.concatAbsolutePath(invocation.getSchemaMeta().getSwagger(), + invocation.getOperationMeta().getOperationPath()); + if (PathCheckUtils.isNotRequiredAuth(requestFullPath, env)) { return nextNode.onFilter(invocation); } String token = invocation.getContext(CoreConst.AUTH_TOKEN); diff --git a/handlers/handler-publickey-auth/src/test/java/org/apache/servicecomb/authentication/provider/TestPathCheckUtils.java b/handlers/handler-publickey-auth/src/test/java/org/apache/servicecomb/authentication/provider/TestPathCheckUtils.java new file mode 100644 index 00000000000..b8ff4623081 --- /dev/null +++ b/handlers/handler-publickey-auth/src/test/java/org/apache/servicecomb/authentication/provider/TestPathCheckUtils.java @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.servicecomb.authentication.provider; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.mockito.Mockito.when; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.servers.Server; +import org.apache.servicecomb.swagger.SwaggerUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.core.env.Environment; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class TestPathCheckUtils { + private static final String KEY_INCLUDE_PATH = "servicecomb.publicKey.accessControl.includePathPatterns"; + + private static final String KEY_EXCLUDE_PATH = "servicecomb.publicKey.accessControl.excludePathPatterns"; + + private static final String BASE_PATH = "/api/v1"; + + private Environment environment; + + private OpenAPI swagger; + + @BeforeEach + public void setUp() { + environment = Mockito.mock(Environment.class); + swagger = new OpenAPI(); + swagger.setServers(new ArrayList<>()); + swagger.getServers().add(new Server().url(BASE_PATH)); + } + + @Test + public void testExcludePathWithBasePathAndExactMatch() { + String operationPath = "/public"; + when(environment.getProperty(KEY_EXCLUDE_PATH, "")).thenReturn(BASE_PATH + operationPath); + + String fullPath = SwaggerUtils.concatAbsolutePath(swagger, operationPath); + assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment), + "Should not require auth for excluded path with exact match"); + } + + @Test + public void testExcludePathWithBasePathAndWildcard() { + when(environment.getProperty(KEY_EXCLUDE_PATH, "")).thenReturn(BASE_PATH + "/public/*"); + + String fullPath = SwaggerUtils.concatAbsolutePath(swagger, "/public/test"); + assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment), + "Should not require auth for excluded path with wildcard"); + + fullPath = SwaggerUtils.concatAbsolutePath(swagger, "/public/nested/path"); + assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment), + "Should not require auth for excluded nested path with wildcard"); + } + + @Test + public void testIncludePathWithBasePath() { + when(environment.getProperty(KEY_EXCLUDE_PATH, "")).thenReturn(""); + when(environment.getProperty(KEY_INCLUDE_PATH, "")).thenReturn(BASE_PATH + "/private/*"); + + String fullPath = SwaggerUtils.concatAbsolutePath(swagger, "/private/resource"); + assertFalse(PathCheckUtils.isNotRequiredAuth(fullPath, environment), + "Should require auth for included path"); + + fullPath = SwaggerUtils.concatAbsolutePath(swagger, "/public/resource"); + assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment), + "Should not require auth for non-included path"); + } + + @Test + public void testExcludeOverrideIncludePath() { + when(environment.getProperty(KEY_EXCLUDE_PATH, "")).thenReturn(BASE_PATH + "/resource"); + when(environment.getProperty(KEY_INCLUDE_PATH, "")).thenReturn(BASE_PATH + "/*"); + + String fullPath = SwaggerUtils.concatAbsolutePath(swagger, "/resource"); + assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment), + "Exclude patterns should override include patterns"); + } + + @Test + public void testMultipleExcludePaths() { + List operationPaths = List.of("/public", "/health", "/metrics/*"); + when(environment.getProperty(KEY_EXCLUDE_PATH, "")).thenReturn(concatPath(BASE_PATH, operationPaths)); + + String fullPath = SwaggerUtils.concatAbsolutePath(swagger, "/public"); + assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment), + "Should not require auth for first exclude path"); + + fullPath = SwaggerUtils.concatAbsolutePath(swagger, "/health"); + assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment), + "Should not require auth for second exclude path"); + + fullPath = SwaggerUtils.concatAbsolutePath(swagger, "/metrics/jvm"); + assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment), + "Should not require auth for wildcard exclude path"); + } + + @Test + public void testDifferentBasePath() { + String basePath = "/different/base"; + String publicOperationPath = "/public"; + String privateOperationPath = "/private"; + swagger.getServers().clear(); + swagger.getServers().add(new Server().url(basePath)); + when(environment.getProperty(KEY_EXCLUDE_PATH, "")).thenReturn(basePath + publicOperationPath); + + String fullPath = SwaggerUtils.concatAbsolutePath(swagger, publicOperationPath); + assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment), + "Should not require auth with different base path"); + + fullPath = SwaggerUtils.concatAbsolutePath(swagger, privateOperationPath); + assertFalse(PathCheckUtils.isNotRequiredAuth(fullPath, environment), + "Should require auth for non-excluded path with different base path"); + } + + @Test + public void testNoBasePath() { + String operationPath = "/public"; + swagger.setServers(null); + when(environment.getProperty(KEY_EXCLUDE_PATH, "")).thenReturn(operationPath); + + String fullPath = SwaggerUtils.concatAbsolutePath(swagger, operationPath); + assertTrue(PathCheckUtils.isNotRequiredAuth(fullPath, environment), + "Should not require auth when no base path is set"); + } + + @Test + public void testEmptyConfiguration() { + when(environment.getProperty(KEY_EXCLUDE_PATH, "")).thenReturn(""); + when(environment.getProperty(KEY_INCLUDE_PATH, "")).thenReturn(""); + + String fullPath = SwaggerUtils.concatAbsolutePath(swagger, "/any/path"); + assertFalse(PathCheckUtils.isNotRequiredAuth(fullPath, environment), + "Should require auth by default when no patterns are configured"); + } + + private String concatPath(String basePath, List paths) { + return paths.stream().map(path -> basePath + path).collect(Collectors.joining(",")); + } +} diff --git a/handlers/handler-router/pom.xml b/handlers/handler-router/pom.xml index 7544f3a5c22..0068002eb7d 100644 --- a/handlers/handler-router/pom.xml +++ b/handlers/handler-router/pom.xml @@ -22,7 +22,7 @@ handlers org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/handlers/handler-tracing-zipkin/pom.xml b/handlers/handler-tracing-zipkin/pom.xml index 841ebb4647a..3644d209bab 100644 --- a/handlers/handler-tracing-zipkin/pom.xml +++ b/handlers/handler-tracing-zipkin/pom.xml @@ -22,7 +22,7 @@ handlers org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/handlers/pom.xml b/handlers/pom.xml index 233c357b299..e74e2c95134 100644 --- a/handlers/pom.xml +++ b/handlers/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default 4.0.0 diff --git a/huawei-cloud/darklaunch/pom.xml b/huawei-cloud/darklaunch/pom.xml index be8605cb946..b4396f87a64 100644 --- a/huawei-cloud/darklaunch/pom.xml +++ b/huawei-cloud/darklaunch/pom.xml @@ -21,7 +21,7 @@ huawei-cloud org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/huawei-cloud/dashboard/pom.xml b/huawei-cloud/dashboard/pom.xml index 47c8db2ef3a..015a43a240a 100644 --- a/huawei-cloud/dashboard/pom.xml +++ b/huawei-cloud/dashboard/pom.xml @@ -21,7 +21,7 @@ huawei-cloud org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/DefaultMonitorDataPublisher.java b/huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/DefaultMonitorDataPublisher.java index cd7d2fc10fe..1209d9d8532 100644 --- a/huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/DefaultMonitorDataPublisher.java +++ b/huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/DefaultMonitorDataPublisher.java @@ -84,8 +84,10 @@ private DashboardAddressManager createDashboardAddressManager() { if (addresses.isEmpty()) { throw new IllegalStateException("dashboard address is not configured."); } + String region = environment.getProperty("servicecomb.datacenter.region"); + String availableZone = environment.getProperty("servicecomb.datacenter.availableZone"); - return new DashboardAddressManager(addresses, EventManager.getEventBus()); + return new DashboardAddressManager(addresses, EventManager.getEventBus(), region, availableZone); } private HttpTransport createHttpTransport(DashboardAddressManager addressManager, RequestConfig requestConfig, @@ -120,8 +122,9 @@ private HttpTransport createHttpTransport(DashboardAddressManager addressManager private static RequestAuthHeaderProvider getRequestAuthHeaderProvider(List authHeaderProviders) { return signRequest -> { + String host = signRequest != null && signRequest.getEndpoint() != null ? signRequest.getEndpoint().getHost() : ""; Map headers = new HashMap<>(); - authHeaderProviders.forEach(provider -> headers.putAll(provider.authHeaders())); + authHeaderProviders.forEach(provider -> headers.putAll(provider.authHeaders(host))); return headers; }; } diff --git a/huawei-cloud/pom.xml b/huawei-cloud/pom.xml index 248839cdf4e..eb70052ed01 100644 --- a/huawei-cloud/pom.xml +++ b/huawei-cloud/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default diff --git a/huawei-cloud/servicestage/pom.xml b/huawei-cloud/servicestage/pom.xml index 28eb37cbe8b..d92064951f9 100644 --- a/huawei-cloud/servicestage/pom.xml +++ b/huawei-cloud/servicestage/pom.xml @@ -21,7 +21,7 @@ huawei-cloud org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 servicestage diff --git a/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/AKSKAuthHeaderProvider.java b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/AKSKAuthHeaderProvider.java index 98d71e6b298..e80e867cab4 100644 --- a/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/AKSKAuthHeaderProvider.java +++ b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/AKSKAuthHeaderProvider.java @@ -19,6 +19,7 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -65,25 +66,21 @@ public class AKSKAuthHeaderProvider implements AuthHeaderProvider, BootStrapServ private final Map headers = new HashMap<>(); - private boolean enabled = true; - private boolean loaded = false; public AKSKAuthHeaderProvider() { } public Map authHeaders() { - if (enabled && !environment.getProperty(CONFIG_AKSK_ENABLED, boolean.class, true)) { - enabled = false; - return headers; + if (!environment.getProperty(CONFIG_AKSK_ENABLED, boolean.class, true)) { + return Collections.emptyMap(); } if (StringUtils.isEmpty(getAccessKey())) { LOGGER.warn("ak sk auth enabled but access key is not configured, disable it at runtime. " + "Config [{}] to false to disable it implicitly.", CONFIG_AKSK_ENABLED); - enabled = false; - return headers; + return Collections.emptyMap(); } if (!loaded) { diff --git a/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/RBACBootStrapService.java b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/RBACBootStrapService.java index b42ea27e849..007e3e56c96 100644 --- a/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/RBACBootStrapService.java +++ b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/RBACBootStrapService.java @@ -42,6 +42,7 @@ import org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties; import org.apache.servicecomb.http.client.common.HttpTransport; import org.apache.servicecomb.http.client.common.HttpTransportFactory; +import org.apache.servicecomb.registry.sc.SCClientUtils; import org.apache.servicecomb.service.center.client.ServiceCenterAddressManager; import org.apache.servicecomb.service.center.client.ServiceCenterClient; import org.apache.servicecomb.service.center.client.ServiceCenterRawClient; @@ -81,7 +82,7 @@ public void startup(Environment environment) { new ServiceCenterClient(new ServiceCenterRawClient.Builder() .setTenantName("default") .setAddressManager(addressManager) - .setHttpTransport(createHttpTransport(environment, sslProperties)).build()); + .setHttpTransport(createHttpTransport(environment, sslProperties)).build(), addressManager); Map clients = new HashMap<>(1); clients.put(DEFAULT_REGISTRY_NAME, serviceCenterClient); @@ -128,8 +129,8 @@ Cipher getCipher(String cipherName) { } private ServiceCenterAddressManager createAddressManager(Environment environment) { - return new ServiceCenterAddressManager(getProjectName(environment), - getRBACAddressList(environment), EventManager.getEventBus()); + return SCClientUtils.createAddressManager(getProjectName(environment), getRBACAddressList(environment), + environment); } private SSLProperties createSSLProperties(Environment environment) { @@ -233,7 +234,7 @@ private String getProjectName(Environment environment) { } private List getRBACAddressList(Environment environment) { - String address = environment.getProperty(RBAC_ADDRESS, "http://127.0.0.1:30100)"); + String address = environment.getProperty(RBAC_ADDRESS, "http://127.0.0.1:30100"); return Arrays.asList(address.split(",")); } diff --git a/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenAuthHeaderProvider.java b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenAuthHeaderProvider.java index 6698f99f83b..19bd550602b 100644 --- a/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenAuthHeaderProvider.java +++ b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenAuthHeaderProvider.java @@ -26,8 +26,8 @@ public class TokenAuthHeaderProvider implements AuthHeaderProvider { @Override - public Map authHeaders() { - String token = TokenCacheManager.getInstance().getToken(RBACBootStrapService.DEFAULT_REGISTRY_NAME); + public Map authHeaders(String host) { + String token = TokenCacheManager.getInstance().getToken(host); if (StringUtils.isEmpty(token)) { return new HashMap<>(); } diff --git a/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenCacheManager.java b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenCacheManager.java index 205f3738166..b4510bb4238 100644 --- a/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenCacheManager.java +++ b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenCacheManager.java @@ -17,19 +17,16 @@ package org.apache.servicecomb.huaweicloud.servicestage; +import java.net.URI; import java.util.Map; -import java.util.Objects; -import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.StringUtils; import org.apache.servicecomb.foundation.auth.Cipher; -import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx; import org.apache.servicecomb.foundation.common.event.EventManager; -import org.apache.servicecomb.http.client.event.EngineConnectChangedEvent; -import org.apache.servicecomb.service.center.client.OperationEvents; +import org.apache.servicecomb.http.client.event.OperationEvents; import org.apache.servicecomb.service.center.client.ServiceCenterClient; import org.apache.servicecomb.service.center.client.model.RbacTokenRequest; import org.apache.servicecomb.service.center.client.model.RbacTokenResponse; @@ -55,17 +52,15 @@ public final class TokenCacheManager { private static final TokenCacheManager INSTANCE = new TokenCacheManager(); - - private final Map tokenCacheMap; - private Map serviceCenterClients; + private TokenCache tokenCache; + public static TokenCacheManager getInstance() { return INSTANCE; } private TokenCacheManager() { - tokenCacheMap = new ConcurrentHashMapEx<>(); } public void setServiceCenterClients(Map serviceCenterClients) { @@ -73,24 +68,17 @@ public void setServiceCenterClients(Map serviceCent } public void addTokenCache(String registryName, String accountName, String password, Cipher cipher) { - Objects.requireNonNull(registryName, "registryName should not be null!"); - if (tokenCacheMap.containsKey(registryName)) { - LOGGER.warn("duplicate token cache registration for serviceRegistry[{}]", registryName); - return; - } - - tokenCacheMap.put(registryName, new TokenCache(registryName, accountName, password, cipher)); + tokenCache = new TokenCache(registryName, accountName, password, cipher); } - public String getToken(String registryName) { - return Optional.ofNullable(tokenCacheMap.get(registryName)) - .map(TokenCache::getToken) - .orElse(null); + public String getToken(String host) { + if (tokenCache == null) { + return null; + } + return tokenCache.getToken(host); } public class TokenCache { - private static final String UN_AUTHORIZED_CODE_HALF_OPEN = "401302"; - private static final long TOKEN_REFRESH_TIME_IN_SECONDS = 20 * 60 * 1000; private final String registryName; @@ -105,10 +93,6 @@ public class TokenCache { private final Cipher cipher; - private int lastStatusCode; - - private String lastErrorCode; - public TokenCache(String registryName, String accountName, String password, Cipher cipher) { this.registryName = registryName; @@ -128,17 +112,17 @@ public void run() { } }); cache = CacheBuilder.newBuilder() - .maximumSize(1) + .maximumSize(10) .refreshAfterWrite(refreshTime(), TimeUnit.MILLISECONDS) .build(new CacheLoader() { @Override public String load(String key) throws Exception { - return createHeaders(); + return createHeaders(key); } @Override public ListenableFuture reload(String key, String oldValue) throws Exception { - return Futures.submit(() -> createHeaders(), executorService); + return Futures.submit(() -> createHeaders(key), executorService); } }); EventManager.getEventBus().register(this); @@ -147,21 +131,22 @@ public ListenableFuture reload(String key, String oldValue) throws Excep @Subscribe public void onNotPermittedEvent(OperationEvents.UnAuthorizedOperationEvent event) { - this.executorService.submit(() -> { - if (lastStatusCode == Status.UNAUTHORIZED.getStatusCode() && UN_AUTHORIZED_CODE_HALF_OPEN - .equals(lastErrorCode)) { - cache.refresh(registryName); - } - }); + LOGGER.warn("address {} unAuthorized, refresh cache token!", event.getAddress()); + cache.refresh(getHostByAddress(event.getAddress())); } - @Subscribe - public void onEngineConnectChangedEvent(EngineConnectChangedEvent event) { - cache.refresh(registryName); + private String getHostByAddress(String address) { + try { + URI uri = URI.create(address); + return uri.getHost(); + } catch (Exception e) { + LOGGER.error("get host by address [{}] error!", address, e); + return registryName; + } } - private String createHeaders() { - LOGGER.info("start to create RBAC headers"); + private String createHeaders(String host) { + LOGGER.info("start to create RBAC headers for host: {}", host); ServiceCenterClient serviceCenterClient = serviceCenterClients.get(this.registryName); @@ -169,10 +154,7 @@ private String createHeaders() { request.setName(accountName); request.setPassword(new String(cipher.decrypt(password.toCharArray()))); - RbacTokenResponse rbacTokenResponse = serviceCenterClient.queryToken(request); - - this.lastStatusCode = rbacTokenResponse.getStatusCode(); - this.lastErrorCode = rbacTokenResponse.getErrorCode(); + RbacTokenResponse rbacTokenResponse = serviceCenterClient.queryToken(request, host); if (Status.UNAUTHORIZED.getStatusCode() == rbacTokenResponse.getStatusCode() || Status.FORBIDDEN.getStatusCode() == rbacTokenResponse.getStatusCode()) { @@ -185,8 +167,14 @@ private String createHeaders() { LOGGER.warn("service center do not support RBAC token, you should not config account info"); return INVALID_TOKEN; } + if (Status.INTERNAL_SERVER_ERROR.getStatusCode() == rbacTokenResponse.getStatusCode()) { + // return null for server_error, so the token information can be re-fetched on the next call. + // It will prompt 'CacheLoader returned null for key xxx' + LOGGER.warn("service center query RBAC token error!"); + return null; + } - LOGGER.info("refresh token successfully {}", rbacTokenResponse.getStatusCode()); + LOGGER.info("refresh host [{}] token successfully {}", host, rbacTokenResponse.getStatusCode()); return rbacTokenResponse.getToken(); } @@ -194,13 +182,16 @@ protected long refreshTime() { return TOKEN_REFRESH_TIME_IN_SECONDS; } - public String getToken() { + public String getToken(String host) { if (!enabled()) { return null; } - + String address = host; + if (StringUtils.isEmpty(address)) { + address = registryName; + } try { - return cache.get(registryName); + return cache.get(address); } catch (Exception e) { LOGGER.error("failed to create token", e); return null; diff --git a/metrics/metrics-core/pom.xml b/metrics/metrics-core/pom.xml index 346771adc45..c68b483fde9 100644 --- a/metrics/metrics-core/pom.xml +++ b/metrics/metrics-core/pom.xml @@ -21,7 +21,7 @@ metrics org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 @@ -59,16 +59,6 @@ vertx-codegen provided - - org.apache.logging.log4j - log4j-slf4j-impl - test - - - org.apache.logging.log4j - log4j-core - test - org.mockito mockito-inline diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestVertxMetersInitializer.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestVertxMetersInitializer.java index 75b3b8a6084..35ba63b3bdc 100644 --- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestVertxMetersInitializer.java +++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestVertxMetersInitializer.java @@ -45,12 +45,14 @@ import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.vertx.core.AbstractVerticle; import io.vertx.core.DeploymentOptions; +import io.vertx.core.Future; import io.vertx.core.Promise; -import io.vertx.core.file.impl.FileResolverImpl; import io.vertx.core.http.HttpClient; import io.vertx.core.http.HttpClientRequest; +import io.vertx.core.http.HttpClientResponse; import io.vertx.core.http.HttpMethod; import io.vertx.core.http.HttpServer; +import io.vertx.core.impl.SysProps; import io.vertx.ext.web.Router; public class TestVertxMetersInitializer { @@ -64,6 +66,12 @@ public class TestVertxMetersInitializer { Environment environment = Mockito.mock(Environment.class); + LogCollector logCollector = new LogCollector(); + + static HttpClient client; + + static HttpServer server; + static int port; static String body = "body"; @@ -74,16 +82,17 @@ public void start(Promise startPromise) { Router mainRouter = Router.router(vertx); mainRouter.route("/").handler(context -> context.response().end(body)); - HttpServer server = vertx.createHttpServer(); + server = vertx.createHttpServer(); server.requestHandler(mainRouter); - server.listen(0, "0.0.0.0", ar -> { - if (ar.succeeded()) { - port = ar.result().actualPort(); + Future future = server.listen(0, "0.0.0.0"); + future.onComplete((s, f) -> { + if (f == null) { + port = s.actualPort(); startPromise.complete(); return; } - startPromise.fail(ar.cause()); + startPromise.fail(f); }); } } @@ -91,13 +100,16 @@ public void start(Promise startPromise) { public static class TestClientVerticle extends AbstractVerticle { @Override public void start(Promise startPromise) { - HttpClient client = vertx.createHttpClient(); - client.request(HttpMethod.GET, port, "127.0.0.1", "/", ar -> { - if (ar.succeeded()) { - HttpClientRequest request = ar.result(); - request.send(body, resp -> { - if (resp.succeeded()) { - resp.result().bodyHandler((buffer) -> startPromise.complete()); + client = vertx.createHttpClient(); + Future future = client.request(HttpMethod.GET, port, "127.0.0.1", "/"); + future.onComplete((s, f) -> { + if (f == null) { + Future responseFuture = s.send(body); + responseFuture.onComplete((rs, rf) -> { + if (rf == null) { + rs.bodyHandler((buffer) -> startPromise.complete()); + } else { + startPromise.fail(f); } }); } @@ -109,15 +121,22 @@ public void start(Promise startPromise) { public void setup() { Mockito.when(environment.getProperty("servicecomb.transport.eventloop.size", int.class, -1)) .thenReturn(-1); - Mockito.when(environment.getProperty(FileResolverImpl.DISABLE_CP_RESOLVING_PROP_NAME, boolean.class, true)) + Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true)) .thenReturn(true); LegacyPropertyFactory.setEnvironment(environment); HttpClients.load(); } @AfterEach - public void teardown() { + public void tearDown() { + logCollector.clear(); HttpClients.destroy(); + if (client != null) { + client.shutdown(); + } + if (server != null) { + server.shutdown(); + } } @Test @@ -140,14 +159,10 @@ public void init() throws InterruptedException { vertxMetersInitializer.poll(0, 1); List meters = registry.getMeters(); - LogCollector logCollector = new LogCollector(); - testLog(logCollector, meters, true); logCollector.clear(); testLog(logCollector, meters, false); - - logCollector.teardown(); } private void testLog(LogCollector logCollector, List meters, boolean printDetail) { diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestDefaultLogPublisher.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestDefaultLogPublisher.java index aa9270f4eb1..a1867955a60 100644 --- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestDefaultLogPublisher.java +++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestDefaultLogPublisher.java @@ -89,8 +89,8 @@ public void setup() { } @After - public void teardown() { - collector.teardown(); + public void tearDown() { + collector.tearDown(); } @Test diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestInvocationPublishModelFactory.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestInvocationPublishModelFactory.java index ca232aec0f5..483aa6ab75d 100644 --- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestInvocationPublishModelFactory.java +++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestInvocationPublishModelFactory.java @@ -30,7 +30,6 @@ import org.apache.servicecomb.metrics.core.publish.model.DefaultPublishModel; import org.apache.servicecomb.swagger.invocation.InvocationType; import org.apache.servicecomb.swagger.invocation.Response; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.springframework.core.env.Environment; @@ -41,6 +40,8 @@ import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.vertx.core.json.Json; +import org.skyscreamer.jsonassert.JSONAssert; + public class TestInvocationPublishModelFactory { EventBus eventBus = new EventBus(); @@ -60,7 +61,7 @@ public class TestInvocationPublishModelFactory { Environment environment = Mockito.mock(Environment.class); @Test - public void createDefaultPublishModel() { + public void createDefaultPublishModel() throws Exception { Mockito.when(environment.getProperty(METRICS_WINDOW_TIME, int.class, DEFAULT_METRICS_WINDOW_TIME)) .thenReturn(DEFAULT_METRICS_WINDOW_TIME); Mockito.when(environment.getProperty( @@ -170,8 +171,8 @@ public void createDefaultPublishModel() { } } """; - Assertions.assertEquals(Json.encodePrettily(Json.decodeValue(expect, Object.class)), - Json.encodePrettily(model.getConsumer())); + JSONAssert.assertEquals(Json.encodePrettily(Json.decodeValue(expect, Object.class)), + Json.encodePrettily(model.getConsumer()), false); expect = """ { @@ -269,8 +270,8 @@ public void createDefaultPublishModel() { } } """; - Assertions.assertEquals(Json.encodePrettily(Json.decodeValue(expect, Object.class)), - Json.encodePrettily(model.getProducer())); + JSONAssert.assertEquals(Json.encodePrettily(Json.decodeValue(expect, Object.class)), + Json.encodePrettily(model.getProducer()), false); } protected void prepareInvocation() { diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestSlowInvocationLogger.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestSlowInvocationLogger.java index ddfa8adeee8..e09252c4e61 100644 --- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestSlowInvocationLogger.java +++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestSlowInvocationLogger.java @@ -82,8 +82,8 @@ public void setup() { } @AfterEach - public void teardown() { - logCollector.teardown(); + public void tearDown() { + logCollector.tearDown(); } @Test diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestThreadPoolPublishModelFactory.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestThreadPoolPublishModelFactory.java index aaf8756dd95..f00e49180ae 100644 --- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestThreadPoolPublishModelFactory.java +++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestThreadPoolPublishModelFactory.java @@ -24,7 +24,6 @@ import org.apache.servicecomb.foundation.metrics.MetricsBootstrapConfig; import org.apache.servicecomb.metrics.core.ThreadPoolMetersInitializer; import org.apache.servicecomb.metrics.core.publish.model.DefaultPublishModel; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; @@ -36,6 +35,8 @@ import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.mockito.junit.jupiter.MockitoExtension; +import org.skyscreamer.jsonassert.JSONAssert; + @ExtendWith(MockitoExtension.class) @TestMethodOrder(MethodOrderer.MethodName.class) public class TestThreadPoolPublishModelFactory { @@ -61,9 +62,9 @@ public void createThreadPoolMeters() { PublishModelFactory factory = new PublishModelFactory(registry.getMeters()); DefaultPublishModel model = factory.createDefaultPublishModel(); - Assertions.assertEquals( + JSONAssert.assertEquals( """ {"test":{"avgTaskCount":0.0,"avgCompletedTaskCount":0.0,"currentThreadsBusy":0,"maxThreads":0,"poolSize":0,"corePoolSize":0,"queueSize":10,"rejected":0.0}}""", - JsonUtils.writeValueAsString(model.getThreadPools())); + JsonUtils.writeValueAsString(model.getThreadPools()), false); } } diff --git a/metrics/metrics-integration/metrics-prometheus/pom.xml b/metrics/metrics-integration/metrics-prometheus/pom.xml index 59d5f1424e7..20d23c9d567 100644 --- a/metrics/metrics-integration/metrics-prometheus/pom.xml +++ b/metrics/metrics-integration/metrics-prometheus/pom.xml @@ -21,7 +21,7 @@ metrics-integration org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/metrics/metrics-integration/pom.xml b/metrics/metrics-integration/pom.xml index b6eb7af66c2..d989f8bc2a4 100644 --- a/metrics/metrics-integration/pom.xml +++ b/metrics/metrics-integration/pom.xml @@ -22,7 +22,7 @@ metrics org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/metrics/pom.xml b/metrics/pom.xml index b1cd07eef79..95eb85051fc 100644 --- a/metrics/pom.xml +++ b/metrics/pom.xml @@ -24,7 +24,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default diff --git a/parents/default/pom.xml b/parents/default/pom.xml index 6a5be12b1de..b8954d029b8 100644 --- a/parents/default/pom.xml +++ b/parents/default/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb java-chassis-dependencies - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../../dependencies/default diff --git a/parents/pom.xml b/parents/pom.xml index e7bc7555954..8fce5793c5c 100644 --- a/parents/pom.xml +++ b/parents/pom.xml @@ -24,7 +24,7 @@ org.apache.servicecomb java-chassis - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT java-chassis-parents diff --git a/pom.xml b/pom.xml index 3e994ce0829..25882c4ca33 100644 --- a/pom.xml +++ b/pom.xml @@ -23,13 +23,13 @@ org.apache apache - 33 + 35 org.apache.servicecomb java-chassis - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT pom ServiceComb Java Chassis @@ -46,29 +46,29 @@ 3.6.0 4.3.0 - 11.1.0 - 0.45.1 - 3.5.0 - 3.2.7 - 0.8.12 - 3.11.1 + 12.2.0 + 0.48.0 + 3.6.3 + 3.2.8 + 0.8.14 + 3.12.0 2.5 - 3.13.0 - 3.5.2 + 3.15.0 + 3.5.4 3.4.2 - 3.8.0 + 3.9.0 3.2.0 1.7.1 0.6.1 3.19.2 1.47.0 - 10.20.2 + 12.3.1 3.1.1 3.21.0 3.3.0 - 4.8.6.6 - 3.3.5 - 3.5.2 + 4.9.8.2 + 3.5.4 + 3.5.4 @@ -199,7 +199,7 @@ org.codehaus.mojo license-maven-plugin - 2.5.0 + 2.7.1 default-cli @@ -314,11 +314,6 @@ alphabetical - - org.apache.maven.plugins - maven-failsafe-plugin - ${maven-failsafe-plugin.version} - org.apache.maven.plugins maven-jar-plugin @@ -339,7 +334,7 @@ true true Medium - ci/spotbugs/exclude.xml + ${session.executionRootDirectory}/ci/spotbugs/exclude.xml @@ -540,7 +535,6 @@ Date created: - -Xdoclint:none diff --git a/providers/pom.xml b/providers/pom.xml index 3ee7f953544..9bd8a52f271 100644 --- a/providers/pom.xml +++ b/providers/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default providers diff --git a/providers/provider-jaxrs/pom.xml b/providers/provider-jaxrs/pom.xml index dccec12a934..1bd923857c6 100644 --- a/providers/provider-jaxrs/pom.xml +++ b/providers/provider-jaxrs/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb providers - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT provider-jaxrs Java Chassis::Providers::JAXRS diff --git a/providers/provider-pojo/pom.xml b/providers/provider-pojo/pom.xml index 91110c76916..922f544b9f5 100644 --- a/providers/provider-pojo/pom.xml +++ b/providers/provider-pojo/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb providers - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT provider-pojo Java Chassis::Providers::POJO diff --git a/providers/provider-rest-common/pom.xml b/providers/provider-rest-common/pom.xml index 49c1331ba09..075a9f9146b 100644 --- a/providers/provider-rest-common/pom.xml +++ b/providers/provider-rest-common/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb providers - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT provider-rest-common Java Chassis::Providers::Rest Common diff --git a/providers/provider-springmvc/pom.xml b/providers/provider-springmvc/pom.xml index 9f49840dd9c..4792027cc64 100644 --- a/providers/provider-springmvc/pom.xml +++ b/providers/provider-springmvc/pom.xml @@ -23,7 +23,7 @@ org.apache.servicecomb providers - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT provider-springmvc Java Chassis::Providers::Spring MVC diff --git a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java index 3cbc2c93f04..ba056e180fb 100644 --- a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java +++ b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java @@ -20,6 +20,7 @@ import java.io.OutputStream; import java.lang.reflect.Type; import java.net.URI; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -150,6 +151,11 @@ public URI getURI() { return uri; } + @Override + public Map getAttributes() { + return Collections.emptyMap(); + } + @Override public HttpHeaders getHeaders() { return httpHeaders; diff --git a/service-registry/pom.xml b/service-registry/pom.xml index 213f0b0f2d6..252d89eb433 100644 --- a/service-registry/pom.xml +++ b/service-registry/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default 4.0.0 @@ -38,5 +38,6 @@ registry-nacos registry-zookeeper registry-etcd + registry-consul diff --git a/service-registry/registry-consul/pom.xml b/service-registry/registry-consul/pom.xml new file mode 100644 index 00000000000..380b9ea45fc --- /dev/null +++ b/service-registry/registry-consul/pom.xml @@ -0,0 +1,54 @@ + + + + + 4.0.0 + + org.apache.servicecomb + service-registry-parent + 3.4.0-SNAPSHOT + + + registry-consul + Java Chassis::Service Registry::Consul + + + + org.kiwiproject + consul-client + + + org.apache.servicecomb + foundation-common + + + org.apache.servicecomb + foundation-registry + + + org.apache.servicecomb + java-chassis-core + + + com.google.code.gson + gson + + + diff --git a/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulConfiguration.java b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulConfiguration.java new file mode 100644 index 00000000000..36422f0f110 --- /dev/null +++ b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulConfiguration.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.registry.consul; + +import com.google.common.net.HostAndPort; + +import org.apache.commons.lang3.StringUtils; +import org.apache.servicecomb.config.DataCenterProperties; +import org.apache.servicecomb.registry.RegistrationId; +import org.apache.servicecomb.registry.consul.config.ConsulDiscoveryProperties; +import org.apache.servicecomb.registry.consul.config.ConsulProperties; +import org.kiwiproject.consul.Consul; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +@ConditionalOnProperty(prefix = "servicecomb.registry.consul", name = "enabled", matchIfMissing = true) +@Configuration +public class ConsulConfiguration { + + @Bean + @ConfigurationProperties(prefix = ConsulConst.CONSUL_REGISTRY_PREFIX) + @ConditionalOnMissingBean + public ConsulProperties consulProperties() { + return new ConsulProperties(); + } + + @Bean + @ConfigurationProperties(prefix = ConsulConst.CONSUL_DISCOVERY_REGISTRY_PREFIX) + @ConditionalOnMissingBean + public ConsulDiscoveryProperties consulDiscoveryProperties() { + return new ConsulDiscoveryProperties(); + } + + @Bean + @ConditionalOnBean(value = {ConsulProperties.class, ConsulDiscoveryProperties.class}) + @ConditionalOnMissingBean + public Consul consulClient(ConsulProperties consulProperties, ConsulDiscoveryProperties consulDiscoveryProperties) { + Consul.Builder builder = Consul.builder() + .withHostAndPort(HostAndPort.fromParts(consulProperties.getHost(), consulProperties.getPort())); + if (StringUtils.isNotBlank(consulDiscoveryProperties.getAclToken())) { + builder.withAclToken(consulDiscoveryProperties.getAclToken()); + } + return builder.build(); + } + + @Bean + @ConditionalOnBean(value = {Consul.class, Environment.class, RegistrationId.class, DataCenterProperties.class}) + @ConditionalOnMissingBean + public ConsulDiscovery consulDiscovery() { + return new ConsulDiscovery(); + } + + @Bean + @ConditionalOnBean(value = {Consul.class, Environment.class, RegistrationId.class, DataCenterProperties.class}) + @ConditionalOnMissingBean + public ConsulRegistration consulRegistration() { + return new ConsulRegistration(); + } +} diff --git a/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulConst.java b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulConst.java new file mode 100644 index 00000000000..7074c34a3e0 --- /dev/null +++ b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulConst.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.registry.consul; + +public class ConsulConst { + + public static final String CONSUL_REGISTRY_NAME = "consul-registry"; + + public static final String CONSUL_REGISTRY_PREFIX = "servicecomb.registry.consul"; + + public static final String CONSUL_DISCOVERY_REGISTRY_PREFIX = "servicecomb.registry.consul.discovery"; + + public static final String CONSUL_DEFAULT_ENVIRONMENT = "production"; +} diff --git a/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulDiscovery.java b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulDiscovery.java new file mode 100644 index 00000000000..ce16ccc47b3 --- /dev/null +++ b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulDiscovery.java @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.registry.consul; + +import com.google.common.collect.Lists; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import jakarta.annotation.Resource; +import jakarta.validation.constraints.NotNull; + +import org.apache.servicecomb.config.BootStrapProperties; +import org.apache.servicecomb.registry.api.Discovery; +import org.apache.servicecomb.registry.consul.config.ConsulDiscoveryProperties; +import org.apache.servicecomb.registry.consul.config.ConsulProperties; +import org.kiwiproject.consul.Consul; +import org.kiwiproject.consul.HealthClient; +import org.kiwiproject.consul.cache.ServiceHealthCache; +import org.kiwiproject.consul.cache.ServiceHealthKey; +import org.kiwiproject.consul.model.health.Service; +import org.kiwiproject.consul.model.health.ServiceHealth; +import org.kiwiproject.consul.option.Options; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.env.Environment; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class ConsulDiscovery implements Discovery { + + private static final Logger LOGGER = LoggerFactory.getLogger(ConsulDiscovery.class); + + @Resource + private ConsulProperties consulProperties; + + @Resource + private ConsulDiscoveryProperties consulDiscoveryProperties; + + @Resource + private Consul consulClient; + + @Resource + private Environment environment; + + private List consulDiscoveryInstanceList; + + private InstanceChangedListener instanceChangedListener; + + private ServiceHealthCache svHealth; + + @Override + public String name() { + return ConsulConst.CONSUL_REGISTRY_NAME; + } + + @Override + public boolean enabled(String application, String serviceName) { + return consulDiscoveryProperties.isEnabled(); + } + + @Override + public List findServiceInstances(String application, String serviceName) { + LOGGER.info("findServiceInstances application:{}, serviceName:{}", application, serviceName); + consulDiscoveryInstanceList = getInstances(serviceName); + return consulDiscoveryInstanceList; + } + + @Override + public List findServices(String application) { + LOGGER.info("ConsulDiscovery findServices(application={})", application); + Map> response = consulClient.catalogClient().getServices().getResponse(); + if (!CollectionUtils.isEmpty(response)) { + return Lists.newArrayList(response.keySet()); + } + return Lists.newArrayList(); + } + + @Override + public void setInstanceChangedListener(InstanceChangedListener instanceChangedListener) { + this.instanceChangedListener = instanceChangedListener; + } + + @Override + public boolean enabled() { + return consulDiscoveryProperties.isEnabled(); + } + + @Override + public void init() { + LOGGER.info("ConsulDiscovery init"); + } + + @Override + public void run() { + LOGGER.info("ConsulDiscovery run"); + String serviceName = BootStrapProperties.readServiceName(environment); + HealthClient healthClient = consulClient.healthClient(); + svHealth = ServiceHealthCache.newCache(healthClient, serviceName, true, Options.BLANK_QUERY_OPTIONS, + consulDiscoveryProperties.getWatchSeconds()); + svHealth.addListener((Map newValues) -> instanceChangedListener.onInstanceChanged( + name(), BootStrapProperties.readApplication(environment), serviceName, getInstances(serviceName))); + svHealth.start(); + } + + @Override + public void destroy() { + if (svHealth != null) { + svHealth.stop(); + } + String serviceId = consulDiscoveryProperties.getServiceId(); + LOGGER.info("ConsulDiscovery destroy consul service id={}", serviceId); + if (consulClient != null) { + LOGGER.info("ConsulDiscovery consulClient destroy"); + consulClient.agentClient().deregister(serviceId); + consulClient.destroy(); + } + } + + public List getInstances(@NotNull final String serviceName) { + List instances = new ArrayList<>(); + addInstancesToList(instances, serviceName); + return instances; + } + + private void addInstancesToList(List instances, String serviceName) { + List healthServices = getHealthServices(serviceName); + if (!CollectionUtils.isEmpty(healthServices)) { + for (ServiceHealth serviceHealth : healthServices) { + Service service = serviceHealth.getService(); + Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + ConsulInstance consulInstance = gson.fromJson(service.getMeta().get("meta"), ConsulInstance.class); + instances.add(new ConsulDiscoveryInstance(consulInstance)); + } + } + } + + private List getHealthServices(String serviceName) { + HealthClient healthClient = consulClient.healthClient(); + return healthClient.getHealthyServiceInstances(serviceName).getResponse(); + } +} diff --git a/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulDiscoveryInstance.java b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulDiscoveryInstance.java new file mode 100644 index 00000000000..f07e4a40543 --- /dev/null +++ b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulDiscoveryInstance.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.registry.consul; + +import org.apache.servicecomb.registry.api.DiscoveryInstance; + +public class ConsulDiscoveryInstance extends ConsulInstance implements DiscoveryInstance { + + public ConsulDiscoveryInstance(ConsulInstance consulInstance) { + super(consulInstance); + } + + @Override + public String getRegistryName() { + return ConsulConst.CONSUL_REGISTRY_NAME; + } +} diff --git a/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulInstance.java b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulInstance.java new file mode 100644 index 00000000000..722b3bbe28e --- /dev/null +++ b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulInstance.java @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.registry.consul; + +import org.apache.servicecomb.registry.api.DataCenterInfo; +import org.apache.servicecomb.registry.api.MicroserviceInstance; +import org.apache.servicecomb.registry.api.MicroserviceInstanceStatus; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ConsulInstance implements MicroserviceInstance { + private String serviceId; + + private String instanceId; + + private String environment; + + private String application; + + private String serviceName; + + private String alias; + + private String version; + + private String description; + + private DataCenterInfo dataCenterInfo; + + private List endpoints = new ArrayList<>(); + + private Map schemas = new HashMap<>(); + + private Map properties = new HashMap<>(); + + private MicroserviceInstanceStatus status; + + public ConsulInstance() { + + } + + public ConsulInstance(ConsulInstance other) { + this.serviceId = other.serviceId; + this.instanceId = other.instanceId; + this.environment = other.environment; + this.application = other.application; + this.serviceName = other.serviceName; + this.alias = other.alias; + this.version = other.version; + this.description = other.description; + this.dataCenterInfo = other.dataCenterInfo; + this.endpoints = other.endpoints; + this.schemas = other.schemas; + this.properties = other.properties; + this.status = other.status; + } + + public void setServiceId(String serviceId) { + this.serviceId = serviceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + + public void setEnvironment(String environment) { + this.environment = environment; + } + + public void setApplication(String application) { + this.application = application; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public void setAlias(String alias) { + this.alias = alias; + } + + public void setVersion(String version) { + this.version = version; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setDataCenterInfo(DataCenterInfo dataCenterInfo) { + this.dataCenterInfo = dataCenterInfo; + } + + public void setEndpoints(List endpoints) { + this.endpoints = endpoints; + } + + public void setSchemas(Map schemas) { + this.schemas = schemas; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + + public void setStatus(MicroserviceInstanceStatus status) { + this.status = status; + } + + @Override + public String getEnvironment() { + return this.environment; + } + + @Override + public String getApplication() { + return this.application; + } + + @Override + public String getServiceName() { + return this.serviceName; + } + + @Override + public String getAlias() { + return alias; + } + + @Override + public String getVersion() { + return version; + } + + @Override + public DataCenterInfo getDataCenterInfo() { + return dataCenterInfo == null ? new DataCenterInfo() : dataCenterInfo; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public Map getProperties() { + return properties; + } + + @Override + public Map getSchemas() { + return schemas; + } + + @Override + public List getEndpoints() { + return endpoints; + } + + public void addSchema(String schemaId, String content) { + this.schemas.put(schemaId, content); + } + + public void addEndpoint(String endpoint) { + this.endpoints.add(endpoint); + } + + public void addProperty(String key, String value) { + this.properties.put(key, value); + } + + @Override + public String getInstanceId() { + return instanceId; + } + + @Override + public String getServiceId() { + return serviceId; + } + + @Override + public MicroserviceInstanceStatus getStatus() { + return this.status; + } +} diff --git a/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulRegistration.java b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulRegistration.java new file mode 100644 index 00000000000..6458d250fe7 --- /dev/null +++ b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulRegistration.java @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.registry.consul; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import jakarta.annotation.Resource; + +import org.apache.commons.lang3.StringUtils; +import org.apache.servicecomb.config.BootStrapProperties; +import org.apache.servicecomb.config.DataCenterProperties; +import org.apache.servicecomb.core.Endpoint; +import org.apache.servicecomb.core.invocation.endpoint.EndpointUtils; +import org.apache.servicecomb.foundation.common.net.URIEndpointObject; +import org.apache.servicecomb.registry.RegistrationId; +import org.apache.servicecomb.registry.api.DataCenterInfo; +import org.apache.servicecomb.registry.api.MicroserviceInstanceStatus; +import org.apache.servicecomb.registry.api.Registration; +import org.apache.servicecomb.registry.consul.config.ConsulDiscoveryProperties; +import org.kiwiproject.consul.AgentClient; +import org.kiwiproject.consul.Consul; +import org.kiwiproject.consul.model.agent.ImmutableRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.util.CollectionUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public class ConsulRegistration implements Registration { + + private static final Logger LOGGER = LoggerFactory.getLogger(ConsulRegistration.class); + + private ConsulInstance consulInstance; + + @Resource + private ConsulDiscoveryProperties consulDiscoveryProperties; + + @Resource + private Consul consulClient; + + @Resource + private Environment environment; + + @Resource + private DataCenterProperties dataCenterProperties; + + @Resource + private RegistrationId registrationId; + + @Value("${servicecomb.rest.address:127.0.0.1:8080}") + private String restAddress; + + private ImmutableRegistration.Builder registrationBuilder; + + @Override + public String name() { + return ConsulConst.CONSUL_REGISTRY_NAME; + } + + @Override + public ConsulRegistrationInstance getMicroserviceInstance() { + return new ConsulRegistrationInstance(consulInstance); + } + + @Override + public boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status) { + consulInstance.setStatus(status); + Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + Map meta = new HashMap<>(); + meta.put("meta", gson.toJson(consulInstance)); + registrationBuilder.meta(meta); + ImmutableRegistration newService = registrationBuilder.build(); + AgentClient agentClient = consulClient.agentClient(); + agentClient.register(newService); + return true; + } + + @Override + public void addSchema(String schemaId, String content) { + if (consulDiscoveryProperties.isEnableSwaggerRegistration()) { + consulInstance.addSchema(schemaId, content); + } + } + + @Override + public void addEndpoint(String endpoint) { + consulInstance.addEndpoint(endpoint); + } + + @Override + public void addProperty(String key, String value) { + consulInstance.addProperty(key, value); + } + + @Override + public boolean enabled() { + return consulDiscoveryProperties.isEnabled(); + } + + @Override + public void init() { + LOGGER.info("ConsulRegistration init"); + String env = BootStrapProperties.readServiceEnvironment(environment); + if (StringUtils.isEmpty(env)) { + env = ConsulConst.CONSUL_DEFAULT_ENVIRONMENT; + } + String instanceId = registrationId.getInstanceId(); + consulInstance = new ConsulInstance(); + consulInstance.setInstanceId(instanceId); + consulInstance.setEnvironment(env); + consulInstance.setApplication(BootStrapProperties.readApplication(environment)); + consulInstance.setServiceName(BootStrapProperties.readServiceName(environment)); + consulInstance.setAlias(BootStrapProperties.readServiceAlias(environment)); + consulInstance.setDescription(BootStrapProperties.readServiceDescription(environment)); + if (StringUtils.isNotEmpty(dataCenterProperties.getName())) { + DataCenterInfo dataCenterInfo = new DataCenterInfo(); + dataCenterInfo.setName(dataCenterProperties.getName()); + dataCenterInfo.setRegion(dataCenterProperties.getRegion()); + dataCenterInfo.setAvailableZone(dataCenterProperties.getAvailableZone()); + consulInstance.setDataCenterInfo(dataCenterInfo); + } + consulInstance.setProperties(BootStrapProperties.readServiceProperties(environment)); + consulInstance.setVersion(BootStrapProperties.readServiceVersion(environment)); + consulInstance.setStatus( + MicroserviceInstanceStatus.valueOf(BootStrapProperties.readServiceInstanceInitialStatus(environment))); + } + + @Override + public void run() { + LOGGER.info("ConsulRegistration run"); + registrationBuilder = ImmutableRegistration.builder() + .name(consulInstance.getServiceName()); + List endpoints = consulInstance.getEndpoints(); + for (String endpoint : endpoints) { + Endpoint temp = EndpointUtils.parse(endpoint); + if (temp.getAddress() instanceof URIEndpointObject) { + String hostOrIp = ((URIEndpointObject) temp.getAddress()).getHostOrIp(); + int port = ((URIEndpointObject) temp.getAddress()).getPort(); + String serviceId = hostOrIp + ":" + port; + consulDiscoveryProperties.setServiceId(serviceId); + consulInstance.setServiceId(serviceId); + registrationBuilder.id(serviceId); + registrationBuilder.address(hostOrIp); + registrationBuilder.port(port); + break; + } + } + List tags = consulDiscoveryProperties.getTags(); + if (CollectionUtils.isEmpty(tags)) { + tags.add(consulInstance.getServiceName()); + } + registrationBuilder.tags(tags); + Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + Map meta = new HashMap<>(); + meta.put("meta", gson.toJson(consulInstance)); + registrationBuilder.meta(meta); + ImmutableRegistration newService = registrationBuilder.build(); + AgentClient agentClient = consulClient.agentClient(); + agentClient.register(newService); + LOGGER.info("ConsulRegistration newService"); + } + + @Override + public void destroy() { + LOGGER.info("ConsulRegistration destroy"); + } +} diff --git a/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulRegistrationInstance.java b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulRegistrationInstance.java new file mode 100644 index 00000000000..dc0b83eaefc --- /dev/null +++ b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/ConsulRegistrationInstance.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.registry.consul; + + +import org.apache.servicecomb.registry.api.RegistrationInstance; + +public class ConsulRegistrationInstance extends ConsulInstance implements RegistrationInstance { + + public ConsulRegistrationInstance(ConsulInstance instance) { + super(instance); + } +} diff --git a/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/config/ConsulDiscoveryProperties.java b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/config/ConsulDiscoveryProperties.java new file mode 100644 index 00000000000..a6a23192eb4 --- /dev/null +++ b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/config/ConsulDiscoveryProperties.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.registry.consul.config; + +import org.springframework.core.style.ToStringCreator; + +import java.util.ArrayList; +import java.util.List; + + +public class ConsulDiscoveryProperties { + + private String aclToken; + + private List tags = new ArrayList<>(); + + private Boolean enabled = true; + + private Integer watchSeconds = 8; + + private Boolean enableSwaggerRegistration = false; + + private String serviceId; + + public String getAclToken() { + return this.aclToken; + } + + public void setAclToken(String aclToken) { + this.aclToken = aclToken; + } + + public List getTags() { + return this.tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public Boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public Boolean isEnableSwaggerRegistration() { + return enableSwaggerRegistration; + } + + public void setEnableSwaggerRegistration(Boolean enableSwaggerRegistration) { + this.enableSwaggerRegistration = enableSwaggerRegistration; + } + + public Integer getWatchSeconds() { + return watchSeconds; + } + + public void setWatchSeconds(Integer watchSeconds) { + this.watchSeconds = watchSeconds; + } + + public String getServiceId() { + return serviceId; + } + + public void setServiceId(String serviceId) { + this.serviceId = serviceId; + } + + @Override + public String toString() { + return new ToStringCreator(this).append("aclToken", this.aclToken) + .append("enabled", this.enabled) + .append("serviceId", this.serviceId) + .append("tags", this.tags) + .append("watchSeconds", this.watchSeconds) + .toString(); + } +} diff --git a/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/config/ConsulProperties.java b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/config/ConsulProperties.java new file mode 100644 index 00000000000..bb04a758330 --- /dev/null +++ b/service-registry/registry-consul/src/main/java/org/apache/servicecomb/registry/consul/config/ConsulProperties.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.registry.consul.config; + +import jakarta.validation.constraints.NotNull; + +import org.springframework.validation.annotation.Validated; + + +@Validated +public class ConsulProperties { + + @NotNull + private String host = "localhost"; + + private String scheme = "http"; + + @NotNull + private Integer port = 8500; + + private Boolean enabled = true; + + public String getHost() { + return this.host; + } + + public void setHost(String host) { + this.host = host; + } + + public Integer getPort() { + return this.port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public Boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public String getScheme() { + return this.scheme; + } + + public void setScheme(String scheme) { + this.scheme = scheme; + } + + @Override + public String toString() { + return "ConsulProperties{" + "host='" + this.host + '\'' + ", port=" + this.port + ", scheme=" + this.scheme + + ", enabled=" + this.enabled + "}"; + } +} diff --git a/service-registry/registry-consul/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/service-registry/registry-consul/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000000..9a0422d67c2 --- /dev/null +++ b/service-registry/registry-consul/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,18 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +org.apache.servicecomb.registry.consul.ConsulConfiguration diff --git a/service-registry/registry-etcd/pom.xml b/service-registry/registry-etcd/pom.xml index cf48811d342..10c037a03aa 100644 --- a/service-registry/registry-etcd/pom.xml +++ b/service-registry/registry-etcd/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb service-registry-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdDiscoveryInstance.java b/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdDiscoveryInstance.java index 85f5ade0142..d75a3b04cf4 100644 --- a/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdDiscoveryInstance.java +++ b/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdDiscoveryInstance.java @@ -17,19 +17,12 @@ package org.apache.servicecomb.registry.etcd; import org.apache.servicecomb.registry.api.DiscoveryInstance; -import org.apache.servicecomb.registry.api.MicroserviceInstanceStatus; - public class EtcdDiscoveryInstance extends EtcdInstance implements DiscoveryInstance { public EtcdDiscoveryInstance(EtcdInstance other) { super(other); } - @Override - public MicroserviceInstanceStatus getStatus() { - return MicroserviceInstanceStatus.UP; - } - @Override public String getRegistryName() { return EtcdConst.ETCD_REGISTRY_NAME; diff --git a/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdInstance.java b/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdInstance.java index 19fbd8cadf6..071e84bf3bc 100644 --- a/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdInstance.java +++ b/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdInstance.java @@ -23,6 +23,7 @@ import org.apache.servicecomb.registry.api.DataCenterInfo; import org.apache.servicecomb.registry.api.MicroserviceInstance; +import org.apache.servicecomb.registry.api.MicroserviceInstanceStatus; public class EtcdInstance implements MicroserviceInstance { private String serviceId; @@ -49,6 +50,8 @@ public class EtcdInstance implements MicroserviceInstance { private Map properties = new HashMap<>(); + private MicroserviceInstanceStatus status; + public EtcdInstance() { } @@ -66,6 +69,7 @@ public EtcdInstance(EtcdInstance other) { this.endpoints = other.endpoints; this.schemas = other.schemas; this.properties = other.properties; + this.status = other.status; } public void setServiceId(String serviceId) { @@ -116,6 +120,10 @@ public void setProperties(Map properties) { this.properties = properties; } + public void setStatus(MicroserviceInstanceStatus status) { + this.status = status; + } + @Override public String getEnvironment() { return this.environment; @@ -143,7 +151,7 @@ public String getVersion() { @Override public DataCenterInfo getDataCenterInfo() { - return dataCenterInfo; + return dataCenterInfo == null ? new DataCenterInfo() : dataCenterInfo; } @Override @@ -188,6 +196,11 @@ public String getServiceId() { return serviceId; } + @Override + public MicroserviceInstanceStatus getStatus() { + return this.status; + } + @Override public String toString() { return "EtcdInstance{" + diff --git a/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdRegistration.java b/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdRegistration.java index 7f021f7b677..3fabfac4e23 100644 --- a/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdRegistration.java +++ b/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdRegistration.java @@ -98,6 +98,11 @@ public EtcdRegistrationInstance getMicroserviceInstance() { @Override public boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status) { + this.etcdInstance.setStatus(status); + String valueJson = MuteExceptionUtil.builder().withLog("to json, key:{}, value:{}", keyPath, etcdInstance) + .executeFunction(JsonUtils::writeValueAsString, etcdInstance); + register(ByteSequence.from(keyPath, Charset.defaultCharset()), + ByteSequence.from(valueJson, Charset.defaultCharset())); return true; } @@ -146,6 +151,8 @@ public void init() { } etcdInstance.setProperties(BootStrapProperties.readServiceProperties(environment)); etcdInstance.setVersion(BootStrapProperties.readServiceVersion(environment)); + etcdInstance.setStatus( + MicroserviceInstanceStatus.valueOf(BootStrapProperties.readServiceInstanceInitialStatus(environment))); } @Override diff --git a/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdRegistrationInstance.java b/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdRegistrationInstance.java index 444fe867089..3dfa78c338e 100644 --- a/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdRegistrationInstance.java +++ b/service-registry/registry-etcd/src/main/java/org/apache/servicecomb/registry/etcd/EtcdRegistrationInstance.java @@ -16,21 +16,10 @@ */ package org.apache.servicecomb.registry.etcd; -import org.apache.servicecomb.registry.api.MicroserviceInstanceStatus; import org.apache.servicecomb.registry.api.RegistrationInstance; public class EtcdRegistrationInstance extends EtcdInstance implements RegistrationInstance { public EtcdRegistrationInstance(EtcdInstance instance) { super(instance); } - - @Override - public MicroserviceInstanceStatus getInitialStatus() { - return MicroserviceInstanceStatus.STARTING; - } - - @Override - public MicroserviceInstanceStatus getReadyStatus() { - return MicroserviceInstanceStatus.UP; - } } diff --git a/service-registry/registry-lightweight/pom.xml b/service-registry/registry-lightweight/pom.xml index a6b50f92f24..43a27c5cfe6 100644 --- a/service-registry/registry-lightweight/pom.xml +++ b/service-registry/registry-lightweight/pom.xml @@ -22,7 +22,7 @@ service-registry-parent org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/service-registry/registry-lightweight/src/test/java/org/apache/servicecomb/registry/lightweight/MessageTest.java b/service-registry/registry-lightweight/src/test/java/org/apache/servicecomb/registry/lightweight/MessageTest.java index 66181ce87e7..0e79f3296c3 100644 --- a/service-registry/registry-lightweight/src/test/java/org/apache/servicecomb/registry/lightweight/MessageTest.java +++ b/service-registry/registry-lightweight/src/test/java/org/apache/servicecomb/registry/lightweight/MessageTest.java @@ -18,10 +18,12 @@ package org.apache.servicecomb.registry.lightweight; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; import org.junit.jupiter.api.Test; import io.vertx.core.json.Json; +import org.skyscreamer.jsonassert.JSONAssert; class MessageTest { private String toLinuxPrettyJson(Object value) { @@ -33,7 +35,8 @@ private String toLinuxPrettyJson(Object value) { void should_encode_register_type() { Message msg = Message.of(MessageType.REGISTER, new RegisterRequest()); - assertThat(toLinuxPrettyJson(msg)).isEqualTo("" + try { + JSONAssert.assertEquals(toLinuxPrettyJson(msg), "" + "{\n" + " \"type\" : \"REGISTER\",\n" + " \"body\" : {\n" @@ -45,7 +48,11 @@ void should_encode_register_type() { + " \"status\" : null,\n" + " \"endpoints\" : null\n" + " }\n" - + "}"); + + "}", false); + } catch (Exception e) { + fail("Failed to compare JSONs: " + e.getMessage(), e); + } + } @Test @@ -60,14 +67,18 @@ void should_decode_register_type() { void should_encode_unregister_type() { Message msg = Message.of(MessageType.UNREGISTER, new UnregisterRequest()); - assertThat(toLinuxPrettyJson(msg)).isEqualTo("" + try { + JSONAssert.assertEquals(toLinuxPrettyJson(msg), "" + "{\n" + " \"type\" : \"UNREGISTER\",\n" + " \"body\" : {\n" + " \"serviceId\" : null,\n" + " \"instanceId\" : null\n" + " }\n" - + "}"); + + "}", false); + } catch (Exception e) { + fail("Failed to compare JSONs: " + e.getMessage(), e); + } } @Test diff --git a/service-registry/registry-local/pom.xml b/service-registry/registry-local/pom.xml index 49e70cb6bee..e3ddcc5510b 100644 --- a/service-registry/registry-local/pom.xml +++ b/service-registry/registry-local/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb service-registry-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/service-registry/registry-local/src/main/java/org/apache/servicecomb/localregistry/LocalRegistrationInstance.java b/service-registry/registry-local/src/main/java/org/apache/servicecomb/localregistry/LocalRegistrationInstance.java index 2262beab439..e07527636a9 100644 --- a/service-registry/registry-local/src/main/java/org/apache/servicecomb/localregistry/LocalRegistrationInstance.java +++ b/service-registry/registry-local/src/main/java/org/apache/servicecomb/localregistry/LocalRegistrationInstance.java @@ -119,12 +119,7 @@ public String getInstanceId() { } @Override - public MicroserviceInstanceStatus getInitialStatus() { - return MicroserviceInstanceStatus.STARTING; - } - - @Override - public MicroserviceInstanceStatus getReadyStatus() { + public MicroserviceInstanceStatus getStatus() { return MicroserviceInstanceStatus.UP; } diff --git a/service-registry/registry-nacos/pom.xml b/service-registry/registry-nacos/pom.xml index eb1a4b5d914..11e58275235 100644 --- a/service-registry/registry-nacos/pom.xml +++ b/service-registry/registry-nacos/pom.xml @@ -17,35 +17,35 @@ --> - - org.apache.servicecomb - service-registry-parent - 3.3.0-SNAPSHOT - - 4.0.0 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + org.apache.servicecomb + service-registry-parent + 3.4.0-SNAPSHOT + + 4.0.0 - registry-nacos - Java Chassis::Service Registry::Nacos + registry-nacos + Java Chassis::Service Registry::Nacos - - - com.alibaba.nacos - nacos-client - - - org.apache.servicecomb - foundation-common - - - org.apache.servicecomb - foundation-registry - - - org.apache.servicecomb - java-chassis-core - - + + + com.alibaba.nacos + nacos-client + + + org.apache.servicecomb + foundation-common + + + org.apache.servicecomb + foundation-registry + + + org.apache.servicecomb + java-chassis-core + + diff --git a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosConst.java b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosConst.java index b3a7a5dab37..563d1726095 100644 --- a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosConst.java +++ b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosConst.java @@ -57,4 +57,6 @@ public class NacosConst { public static final String NAMING_LOAD_CACHE_AT_START = "namingLoadCacheAtStart"; public static final String NACOS_REGISTRY_NAME = "nacos-registry"; + + public static final String NACOS_STATUS = "nacos-status"; } diff --git a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscovery.java b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscovery.java index bd41ad539e2..dfe2a5739eb 100644 --- a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscovery.java +++ b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscovery.java @@ -25,6 +25,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import com.alibaba.nacos.api.exception.NacosException; + import org.apache.servicecomb.registry.api.Discovery; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; diff --git a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscoveryInstance.java b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscoveryInstance.java index 93c8369a65c..6360d012012 100644 --- a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscoveryInstance.java +++ b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosDiscoveryInstance.java @@ -57,7 +57,15 @@ public NacosDiscoveryInstance(Instance instance, String application, String serv @Override public MicroserviceInstanceStatus getStatus() { - return instance.isEnabled() ? MicroserviceInstanceStatus.UP : MicroserviceInstanceStatus.DOWN; + if (instance.isEnabled()) { + String instanceStatus = instance.getMetadata().get(NacosConst.NACOS_STATUS); + if (StringUtils.isBlank(instanceStatus)) { + return MicroserviceInstanceStatus.UP; + } + return MicroserviceInstanceStatus.valueOf(instanceStatus); + } else { + return MicroserviceInstanceStatus.DOWN; + } } @Override diff --git a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistration.java b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistration.java index c11afaec719..96f41d0670e 100644 --- a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistration.java +++ b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistration.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; +import org.apache.servicecomb.config.BootStrapProperties; import org.apache.servicecomb.config.DataCenterProperties; import org.apache.servicecomb.core.Endpoint; import org.apache.servicecomb.core.invocation.endpoint.EndpointUtils; @@ -65,7 +66,8 @@ public void init() { environment); instance.setInstanceId(instanceId); nacosRegistrationInstance = new NacosRegistrationInstance(instance, environment); - + instance.getMetadata() + .put(NacosConst.NACOS_STATUS, BootStrapProperties.readServiceInstanceInitialStatus(environment)); namingService = NamingServiceManager.buildNamingService(environment, nacosDiscoveryProperties); } @@ -132,9 +134,14 @@ public NacosRegistrationInstance getMicroserviceInstance() { @Override public boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status) { - // Do not support Nacos update status now. Because update status will fail - // due to some unknown reasons(Maybe different constrains in register and maintain api). - return true; + try { + instance.getMetadata().put(NacosConst.NACOS_STATUS, status.name()); + namingService.registerInstance(nacosRegistrationInstance.getServiceName(), + nacosRegistrationInstance.getApplication(), instance); + return true; + } catch (Exception e) { + throw new RuntimeException(e); + } } @Override diff --git a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistrationInstance.java b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistrationInstance.java index 653ce3d8928..7a99f1b2dba 100644 --- a/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistrationInstance.java +++ b/service-registry/registry-nacos/src/main/java/org/apache/servicecomb/registry/nacos/NacosRegistrationInstance.java @@ -104,13 +104,8 @@ public String getInstanceId() { } @Override - public MicroserviceInstanceStatus getInitialStatus() { - return MicroserviceInstanceStatus.STARTING; - } - - @Override - public MicroserviceInstanceStatus getReadyStatus() { - return MicroserviceInstanceStatus.UP; + public MicroserviceInstanceStatus getStatus() { + return MicroserviceInstanceStatus.valueOf(instance.getMetadata().get(NacosConst.NACOS_STATUS)); } public void addSchema(String schemaId, String content) { diff --git a/service-registry/registry-service-center/pom.xml b/service-registry/registry-service-center/pom.xml index bcdbf3ce74e..97910c29054 100644 --- a/service-registry/registry-service-center/pom.xml +++ b/service-registry/registry-service-center/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb service-registry-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/MicroserviceHandler.java b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/MicroserviceHandler.java index 7ff1ec74d85..7ffa409a089 100644 --- a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/MicroserviceHandler.java +++ b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/MicroserviceHandler.java @@ -142,7 +142,8 @@ public static MicroserviceInstance createMicroserviceInstance( properties.putAll(BootStrapProperties.readServiceProperties(environment)); properties.putAll(genCasProperties(environment)); microserviceInstance.setProperties(properties); - microserviceInstance.setStatus(MicroserviceInstanceStatus.valueOf(scConfigurationProperties.getInitialStatus())); + microserviceInstance.setStatus( + MicroserviceInstanceStatus.valueOf(BootStrapProperties.readServiceInstanceInitialStatus(environment))); return microserviceInstance; } diff --git a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCAddressManager.java b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCAddressManager.java index c9bf300a36f..1c8ec27c8a8 100644 --- a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCAddressManager.java +++ b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCAddressManager.java @@ -49,28 +49,25 @@ public enum Type { private static final Logger LOGGER = LoggerFactory.getLogger(SCAddressManager.class); - private boolean initialized = false; - private final ServiceCenterClient serviceCenterClient; private final SCRegistration scRegistration; private final SCConfigurationProperties configurationProperties; + private final Map> lastEngineEndpointsCache = new HashMap<>(); + public SCAddressManager(SCConfigurationProperties configurationProperties, ServiceCenterClient serviceCenterClient, SCRegistration scRegistration) { this.configurationProperties = configurationProperties; this.serviceCenterClient = serviceCenterClient; this.scRegistration = scRegistration; - EventManager.getEventBus().register(this); + scRegistration.getEventBus().register(this); } @Subscribe public void onHeartBeatEvent(HeartBeatEvent event) { - if (initialized) { - return; - } if (event.isSuccess() && configurationProperties.isAutoDiscovery()) { for (Type type : Type.values()) { initEndPort(type.name()); @@ -79,19 +76,30 @@ public void onHeartBeatEvent(HeartBeatEvent event) { } private void initEndPort(String key) { - List instances = findServiceInstance("default", - key, "0+"); - if ("SERVICECENTER".equals(key) && !instances.isEmpty()) { - initialized = true; - } - Map> zoneAndRegion = generateZoneAndRegionAddress(instances); + List instances = findServiceInstance("default", key, "0+"); + HashSet currentEngineEndpoints = new HashSet<>(); + Map> zoneAndRegion = generateZoneAndRegionAddress(instances, currentEngineEndpoints); if (zoneAndRegion == null) { return; } - EventManager.post(new RefreshEndpointEvent(zoneAndRegion, key)); + if (isEngineEndpointsChanged(lastEngineEndpointsCache.get(key), currentEngineEndpoints)) { + LOGGER.info("auto discovery service [{}] addresses: [{}]", key, zoneAndRegion); + lastEngineEndpointsCache.put(key, currentEngineEndpoints); + EventManager.post(new RefreshEndpointEvent(zoneAndRegion, key)); + } + } + + private boolean isEngineEndpointsChanged(Set lastEngineEndpoints, Set currentEngineEndpoints) { + if (lastEngineEndpoints == null || lastEngineEndpoints.isEmpty()) { + return true; + } + HashSet compareTemp = new HashSet<>(lastEngineEndpoints); + compareTemp.removeAll(currentEngineEndpoints); + return !compareTemp.isEmpty() || lastEngineEndpoints.size() != currentEngineEndpoints.size(); } - private Map> generateZoneAndRegionAddress(List instances) { + private Map> generateZoneAndRegionAddress(List instances, + HashSet currentEngineEndpoints) { if (instances.isEmpty()) { return null; } @@ -107,6 +115,7 @@ private Map> generateZoneAndRegionAddress(List(sameZone)); zoneAndRegion.put("sameRegion", new ArrayList<>(sameRegion)); diff --git a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCClientUtils.java b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCClientUtils.java index b248f467610..f9371926a1d 100644 --- a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCClientUtils.java +++ b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCClientUtils.java @@ -17,9 +17,12 @@ package org.apache.servicecomb.registry.sc; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; @@ -50,23 +53,69 @@ public class SCClientUtils { private static final Logger LOGGER = LoggerFactory.getLogger(SCClientUtils.class); - public static ServiceCenterAddressManager createAddressManager(SCConfigurationProperties discoveryProperties) { + // Compatible chassis multi-registration center + private static final Map serviceAddressManagers = new ConcurrentHashMap<>(); + + public static ServiceCenterAddressManager createAddressManager(SCConfigurationProperties discoveryProperties, + Environment environment) { List addresses = ConfigUtil.parseArrayValue(discoveryProperties.getAddress()); - LOGGER.info("initialize discovery server={}", addresses); - return new ServiceCenterAddressManager("default", addresses, EventManager.getEventBus()); + return createAddressManager("default", addresses, environment); + } + + /** + * Ensure that the ServiceCenterAddressManager in the client created for RBAC authentication and registry discovery + * is the same. This ensures that when an error is reported due to the registry center address being unavailable, + * the authentication and registry discovery remain consistent. + * + * @param projectName projectName + * @param addresses engine address + * @param environment environment + * @return Service Center Address Manager + */ + public static ServiceCenterAddressManager createAddressManager(String projectName, List addresses, + Environment environment) { + if (getServiceCenterAddressManager(addresses) == null) { + synchronized (SCClientUtils.class) { + if (getServiceCenterAddressManager(addresses) == null) { + String key = String.join(",", addresses); + LOGGER.info("initialize discovery server={}", addresses); + String region = environment.getProperty("servicecomb.datacenter.region"); + String availableZone = environment.getProperty("servicecomb.datacenter.availableZone"); + ServiceCenterAddressManager addressManager = new ServiceCenterAddressManager(projectName, addresses, + EventManager.getEventBus(), region, availableZone); + serviceAddressManagers.put(key, addressManager); + return addressManager; + } + } + } + return getServiceCenterAddressManager(addresses); + } + + private static ServiceCenterAddressManager getServiceCenterAddressManager(List addresses) { + String forwardKey = String.join(",", addresses); + List tempAddr = new ArrayList<>(addresses); + Collections.reverse(tempAddr); + String reverseKey = String.join(",", tempAddr); + if (serviceAddressManagers.get(forwardKey) != null) { + return serviceAddressManagers.get(forwardKey); + } + if (serviceAddressManagers.get(reverseKey) != null) { + return serviceAddressManagers.get(reverseKey); + } + return null; } // add other headers needed for registration by new ServiceCenterClient(...) public static ServiceCenterClient serviceCenterClient(SCConfigurationProperties discoveryProperties, Environment environment) { - ServiceCenterAddressManager addressManager = createAddressManager(discoveryProperties); + ServiceCenterAddressManager addressManager = createAddressManager(discoveryProperties, environment); SSLProperties sslProperties = buildSslProperties(addressManager, environment); return new ServiceCenterClient(new ServiceCenterRawClient.Builder() .setTenantName("default") .setAddressManager(addressManager) - .setHttpTransport(createHttpTransport(environment, sslProperties)).build()); + .setHttpTransport(createHttpTransport(environment, sslProperties)).build(), addressManager); } private static HttpTransport createHttpTransport(Environment environment, SSLProperties sslProperties) { @@ -135,7 +184,7 @@ private static SSLProperties buildSslProperties(ServiceCenterAddressManager addr public static ServiceCenterWatch serviceCenterWatch(SCConfigurationProperties discoveryProperties, List authHeaderProviders, Environment environment) { - ServiceCenterAddressManager addressManager = createAddressManager(discoveryProperties); + ServiceCenterAddressManager addressManager = createAddressManager(discoveryProperties, environment); SSLProperties sslProperties = buildSslProperties(addressManager, environment); return new ServiceCenterWatch(addressManager, sslProperties, getRequestAuthHeaderProvider(authHeaderProviders), "default", new HashMap<>(), EventManager.getEventBus()); @@ -143,8 +192,9 @@ public static ServiceCenterWatch serviceCenterWatch(SCConfigurationProperties di private static RequestAuthHeaderProvider getRequestAuthHeaderProvider(List authHeaderProviders) { return signRequest -> { + String host = signRequest != null && signRequest.getEndpoint() != null ? signRequest.getEndpoint().getHost() : ""; Map headers = new HashMap<>(); - authHeaderProviders.forEach(provider -> headers.putAll(provider.authHeaders())); + authHeaderProviders.forEach(provider -> headers.putAll(provider.authHeaders(host))); return headers; }; } diff --git a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCConfigurationProperties.java b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCConfigurationProperties.java index 784f711cf59..5ac431406a3 100644 --- a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCConfigurationProperties.java +++ b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCConfigurationProperties.java @@ -49,8 +49,6 @@ public class SCConfigurationProperties { private boolean autoDiscovery = false; - private String initialStatus = "STARTING"; - private boolean watch = false; private long registrationWaitTimeInMillis = 30000; @@ -140,14 +138,6 @@ public void setHealthCheckTimes(int healthCheckTimes) { this.healthCheckTimes = healthCheckTimes; } - public String getInitialStatus() { - return initialStatus; - } - - public void setInitialStatus(String initialStatus) { - this.initialStatus = initialStatus; - } - public boolean isWatch() { return watch; } diff --git a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCDiscoveryInstance.java b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCDiscoveryInstance.java index 28ef4e37b0a..f3b7ffe4403 100644 --- a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCDiscoveryInstance.java +++ b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCDiscoveryInstance.java @@ -76,9 +76,12 @@ public String getVersion() { @Override public DataCenterInfo getDataCenterInfo() { - return new DataCenterInfo(microserviceInstance.getDataCenterInfo().getName(), - microserviceInstance.getDataCenterInfo().getRegion(), - microserviceInstance.getDataCenterInfo().getAvailableZone()); + if (microserviceInstance.getDataCenterInfo() != null) { + return new DataCenterInfo(microserviceInstance.getDataCenterInfo().getName(), + microserviceInstance.getDataCenterInfo().getRegion(), + microserviceInstance.getDataCenterInfo().getAvailableZone()); + } + return new DataCenterInfo(); } @Override diff --git a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCRegistration.java b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCRegistration.java index e37f54b676b..6692f61c6c7 100644 --- a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCRegistration.java +++ b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCRegistration.java @@ -88,7 +88,6 @@ public void setEnvironment(Environment environment) { this.environment = environment; } - @Override public void init() { microservice = MicroserviceHandler.createMicroservice( @@ -105,6 +104,10 @@ public void init() { eventBus); serviceCenterRegistration.setMicroservice(microservice); serviceCenterRegistration.setMicroserviceInstance(microserviceInstance); + serviceCenterRegistration.setHeartBeatInterval( + TimeUnit.SECONDS.toMillis(configurationProperties.getHealthCheckIntervalInSeconds())); + serviceCenterRegistration.setHeartBeatRequestTimeout( + configurationProperties.getHealthCheckRequestTimeoutInMillis()); registrationInstance = new SCRegistrationInstance(microservice, microserviceInstance, serviceCenterRegistration); eventBus.register(this); } @@ -195,4 +198,8 @@ public Microservice getBackendMicroservice() { public MicroserviceInstance getBackendMicroserviceInstance() { return microserviceInstance; } + + EventBus getEventBus() { + return eventBus; + } } diff --git a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCRegistrationInstance.java b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCRegistrationInstance.java index 36416972a73..cfe53692eeb 100644 --- a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCRegistrationInstance.java +++ b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCRegistrationInstance.java @@ -34,8 +34,7 @@ public class SCRegistrationInstance implements RegistrationInstance { private final ServiceCenterRegistration serviceCenterRegistration; - public SCRegistrationInstance(Microservice microservice, - MicroserviceInstance microserviceInstance, + public SCRegistrationInstance(Microservice microservice, MicroserviceInstance microserviceInstance, ServiceCenterRegistration serviceCenterRegistration) { this.microservice = microservice; this.microserviceInstance = microserviceInstance; @@ -107,15 +106,10 @@ public String getServiceId() { } @Override - public MicroserviceInstanceStatus getInitialStatus() { + public MicroserviceInstanceStatus getStatus() { return MicroserviceInstanceStatus.valueOf(microserviceInstance.getStatus().name()); } - @Override - public MicroserviceInstanceStatus getReadyStatus() { - return MicroserviceInstanceStatus.UP; - } - public Microservice getBackendMicroservice() { return microservice; } diff --git a/service-registry/registry-zero-config/pom.xml b/service-registry/registry-zero-config/pom.xml index f671507bdea..c9a6569f1bc 100644 --- a/service-registry/registry-zero-config/pom.xml +++ b/service-registry/registry-zero-config/pom.xml @@ -22,7 +22,7 @@ service-registry-parent org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/ZeroConfigRegistrationInstance.java b/service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/ZeroConfigRegistrationInstance.java index 61864c96495..9e1955b24a8 100644 --- a/service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/ZeroConfigRegistrationInstance.java +++ b/service-registry/registry-zero-config/src/main/java/org/apache/servicecomb/zeroconfig/ZeroConfigRegistrationInstance.java @@ -87,12 +87,7 @@ public String getInstanceId() { } @Override - public MicroserviceInstanceStatus getInitialStatus() { - return MicroserviceInstanceStatus.STARTING; - } - - @Override - public MicroserviceInstanceStatus getReadyStatus() { + public MicroserviceInstanceStatus getStatus() { return MicroserviceInstanceStatus.UP; } diff --git a/service-registry/registry-zookeeper/pom.xml b/service-registry/registry-zookeeper/pom.xml index fa09ecd9320..e5ba4236e18 100644 --- a/service-registry/registry-zookeeper/pom.xml +++ b/service-registry/registry-zookeeper/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb service-registry-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperDiscoveryInstance.java b/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperDiscoveryInstance.java index f33b05fb7f7..b01ad50830e 100644 --- a/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperDiscoveryInstance.java +++ b/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperDiscoveryInstance.java @@ -17,18 +17,12 @@ package org.apache.servicecomb.registry.zookeeper; import org.apache.servicecomb.registry.api.DiscoveryInstance; -import org.apache.servicecomb.registry.api.MicroserviceInstanceStatus; public class ZookeeperDiscoveryInstance extends ZookeeperInstance implements DiscoveryInstance { public ZookeeperDiscoveryInstance(ZookeeperInstance other) { super(other); } - @Override - public MicroserviceInstanceStatus getStatus() { - return MicroserviceInstanceStatus.UP; - } - @Override public String getRegistryName() { return ZookeeperConst.ZOOKEEPER_REGISTRY_NAME; diff --git a/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperInstance.java b/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperInstance.java index 725816b24a2..b919d97855f 100644 --- a/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperInstance.java +++ b/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperInstance.java @@ -23,6 +23,7 @@ import org.apache.servicecomb.registry.api.DataCenterInfo; import org.apache.servicecomb.registry.api.MicroserviceInstance; +import org.apache.servicecomb.registry.api.MicroserviceInstanceStatus; public class ZookeeperInstance implements MicroserviceInstance { private String serviceId; @@ -49,6 +50,8 @@ public class ZookeeperInstance implements MicroserviceInstance { private Map properties = new HashMap<>(); + private MicroserviceInstanceStatus status; + public ZookeeperInstance() { } @@ -66,6 +69,7 @@ public ZookeeperInstance(ZookeeperInstance other) { this.endpoints = other.endpoints; this.schemas = other.schemas; this.properties = other.properties; + this.status = other.status; } public void setServiceId(String serviceId) { @@ -116,6 +120,10 @@ public void setProperties(Map properties) { this.properties = properties; } + public void setStatus(MicroserviceInstanceStatus status) { + this.status = status; + } + @Override public String getEnvironment() { return this.environment; @@ -143,7 +151,7 @@ public String getVersion() { @Override public DataCenterInfo getDataCenterInfo() { - return dataCenterInfo; + return dataCenterInfo == null ? new DataCenterInfo() : dataCenterInfo; } @Override @@ -187,4 +195,9 @@ public String getInstanceId() { public String getServiceId() { return serviceId; } + + @Override + public MicroserviceInstanceStatus getStatus() { + return this.status; + } } diff --git a/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperRegistration.java b/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperRegistration.java index c799cc0474a..55df0d42702 100644 --- a/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperRegistration.java +++ b/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperRegistration.java @@ -79,6 +79,8 @@ public AppConfigurationEntry[] getAppConfigurationEntry(String name) { private RegistrationId registrationId; + private ServiceDiscovery dis; + @Autowired @SuppressWarnings("unused") public void setEnvironment(Environment environment) { @@ -125,6 +127,9 @@ public void init() { } zookeeperInstance.setProperties(BootStrapProperties.readServiceProperties(environment)); zookeeperInstance.setVersion(BootStrapProperties.readServiceVersion(environment)); + + zookeeperInstance.setStatus( + MicroserviceInstanceStatus.valueOf(BootStrapProperties.readServiceInstanceInitialStatus(environment))); try { this.instance = ServiceInstance.builder().name(zookeeperInstance.getServiceName()) .id(zookeeperInstance.getInstanceId()).payload(zookeeperInstance).build(); @@ -155,7 +160,7 @@ public void run() { client.start(); JsonInstanceSerializer serializer = new JsonInstanceSerializer<>(ZookeeperInstance.class); - ServiceDiscovery dis = ServiceDiscoveryBuilder.builder(ZookeeperInstance.class) + dis = ServiceDiscoveryBuilder.builder(ZookeeperInstance.class) .client(client) .basePath(basePath + "/" + BootStrapProperties.readApplication(environment)) .serializer(serializer) @@ -187,7 +192,12 @@ public ZookeeperRegistrationInstance getMicroserviceInstance() { @Override public boolean updateMicroserviceInstanceStatus(MicroserviceInstanceStatus status) { - // not support yet + this.instance.getPayload().setStatus(status); + try { + dis.updateService(instance); + } catch (Exception e) { + throw new IllegalStateException(e); + } return true; } diff --git a/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperRegistrationInstance.java b/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperRegistrationInstance.java index 6c098705b03..e5caed18960 100644 --- a/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperRegistrationInstance.java +++ b/service-registry/registry-zookeeper/src/main/java/org/apache/servicecomb/registry/zookeeper/ZookeeperRegistrationInstance.java @@ -16,21 +16,10 @@ */ package org.apache.servicecomb.registry.zookeeper; -import org.apache.servicecomb.registry.api.MicroserviceInstanceStatus; import org.apache.servicecomb.registry.api.RegistrationInstance; public class ZookeeperRegistrationInstance extends ZookeeperInstance implements RegistrationInstance { public ZookeeperRegistrationInstance(ZookeeperInstance instance) { super(instance); } - - @Override - public MicroserviceInstanceStatus getInitialStatus() { - return MicroserviceInstanceStatus.STARTING; - } - - @Override - public MicroserviceInstanceStatus getReadyStatus() { - return MicroserviceInstanceStatus.UP; - } } diff --git a/solutions/pom.xml b/solutions/pom.xml index b284c853266..4203f65309b 100644 --- a/solutions/pom.xml +++ b/solutions/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default 4.0.0 diff --git a/solutions/solution-basic/pom.xml b/solutions/solution-basic/pom.xml index 2264a8be138..1bb51a4b88c 100644 --- a/solutions/solution-basic/pom.xml +++ b/solutions/solution-basic/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb solutions - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index a20b4869bb2..b96de480b73 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default diff --git a/spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-servlet/pom.xml b/spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-servlet/pom.xml index 9e261dd5676..c3fa579baee 100644 --- a/spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-servlet/pom.xml +++ b/spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-servlet/pom.xml @@ -22,7 +22,7 @@ java-chassis-spring-boot-starters org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-standalone/pom.xml b/spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-standalone/pom.xml index 7b705ef961a..cd8d007109f 100644 --- a/spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-standalone/pom.xml +++ b/spring-boot/spring-boot-starters/java-chassis-spring-boot-starter-standalone/pom.xml @@ -22,7 +22,7 @@ java-chassis-spring-boot-starters org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/spring-boot/spring-boot-starters/pom.xml b/spring-boot/spring-boot-starters/pom.xml index ea528b5ab51..8c3eecd55ed 100644 --- a/spring-boot/spring-boot-starters/pom.xml +++ b/spring-boot/spring-boot-starters/pom.xml @@ -22,7 +22,7 @@ java-chassis-spring-boot org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/swagger/pom.xml b/swagger/pom.xml index 06f9b452748..5009d6dbc8f 100644 --- a/swagger/pom.xml +++ b/swagger/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default swagger diff --git a/swagger/swagger-generator/generator-core/pom.xml b/swagger/swagger-generator/generator-core/pom.xml index ffec1079fb1..768f6ecd054 100644 --- a/swagger/swagger-generator/generator-core/pom.xml +++ b/swagger/swagger-generator/generator-core/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb swagger-generator - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT swagger-generator-core Java Chassis::Swagger::Generator::Core diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/SwaggerUtils.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/SwaggerUtils.java index 211a612a861..c1751b728a8 100644 --- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/SwaggerUtils.java +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/SwaggerUtils.java @@ -445,4 +445,24 @@ public static boolean methodExists(PathItem pathItem, String httpMethod) { default -> false; }; } + + public static String concatAbsolutePath(OpenAPI swagger, String operationPath) { + String basePath = getBasePath(swagger); + return concatPath(basePath, operationPath); + } + + /** + * Concat the two paths to an absolute path, without end of '/'. + *

+ * e.g. "/" + "/ope" = /ope + * e.g. "/prefix" + "/ope" = /prefix/ope + */ + public static String concatPath(String basePath, String operationPath) { + return ("/" + nonNullify(basePath) + "/" + nonNullify(operationPath)) + .replaceAll("/{2,}", "/"); + } + + private static String nonNullify(String path) { + return path == null ? "" : path; + } } diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/introspector/JsonPropertyIntrospector.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/introspector/JsonPropertyIntrospector.java index bf647c15b64..4e377b81a11 100644 --- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/introspector/JsonPropertyIntrospector.java +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/introspector/JsonPropertyIntrospector.java @@ -26,6 +26,8 @@ import io.swagger.v3.core.jackson.SwaggerAnnotationIntrospector; +import java.util.Objects; + public class JsonPropertyIntrospector extends SwaggerAnnotationIntrospector { private static final long serialVersionUID = 4157263023893695762L; @@ -47,10 +49,10 @@ public String findEnumValue(Enum value) { @Override public String findPropertyDescription(Annotated annotated) { Class enumClass = annotated.getRawType(); - if (enumClass.isEnum()) { + if (enumClass.isEnum() && Objects.nonNull(annotated.getAnnotated())) { return SwaggerEnum.JDK.findPropertyDescription(enumClass, annotated.getAnnotated().getAnnotations()); } - if (EnumUtils.isDynamicEnum(enumClass)) { + if (EnumUtils.isDynamicEnum(enumClass) && Objects.nonNull(annotated.getAnnotated())) { return SwaggerEnum.DYNAMIC.findPropertyDescription(enumClass, annotated.getAnnotated().getAnnotations()); } diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/unittest/UnitTestSwaggerUtils.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/unittest/UnitTestSwaggerUtils.java index 9448484b083..c3d6270424e 100644 --- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/unittest/UnitTestSwaggerUtils.java +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/unittest/UnitTestSwaggerUtils.java @@ -20,14 +20,16 @@ import java.io.IOException; import java.net.URL; import java.nio.charset.StandardCharsets; -import java.util.Objects; import org.apache.commons.io.IOUtils; import org.apache.servicecomb.swagger.generator.SwaggerGenerator; import org.junit.jupiter.api.Assertions; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import io.swagger.v3.core.util.Yaml; import io.swagger.v3.oas.models.OpenAPI; @@ -81,8 +83,19 @@ public static SwaggerGenerator testSwagger(String resPath, Class cls, String. expectSchema = expectSchema.substring(offset + 4); } - if (!Objects.equals(expectSchema, schema)) { - Assertions.assertEquals(expectSchema, schema); + try { + ObjectMapper yaml = new ObjectMapper(new YAMLFactory()); + JsonNode expected = yaml.readTree(expectSchema); + JsonNode actual = yaml.readTree(schema); + + if (!actual.equals(expected)) { + ObjectMapper json = new ObjectMapper(); + String expectedPretty = json.writerWithDefaultPrettyPrinter().writeValueAsString(expected); + String actualPretty = json.writerWithDefaultPrettyPrinter().writeValueAsString(actual); + Assertions.fail("OpenAPI mismatch.\n=== EXPECTED ===\n" + expectedPretty + "\n=== ACTUAL ===\n" + actualPretty); + } + } catch (Exception e) { + Assertions.fail("Failed to parse/compare OpenAPI YAML: " + e.getMessage(), e); } return generator; diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/extend/module/EnumModuleExtTest.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/extend/module/EnumModuleExtTest.java index e6865b1055b..309f84f4b4a 100644 --- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/extend/module/EnumModuleExtTest.java +++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/extend/module/EnumModuleExtTest.java @@ -56,7 +56,7 @@ public void testEnumModule() throws JsonProcessingException { serializeValue = mapper.writeValueAsString(TestEnum.E_F); Assertions.assertEquals("\"E.F\"", serializeValue); serializeValue = mapper.writeValueAsString(TestEnum.HI); - Assertions.assertEquals("\"HI\"", serializeValue); + Assertions.assertEquals("\"\"", serializeValue); } @Test @@ -64,6 +64,6 @@ public void testEnumModuleModel() { OpenAPI openAPI = new OpenAPI(); Schema schema = SwaggerUtils.resolveTypeSchemas(openAPI, TestEnum.class); Assertions.assertEquals(schema.getType(), "string"); - MatcherAssert.assertThat((List) schema.getEnum(), contains("AB", "C-D", "E.F", "HI")); + MatcherAssert.assertThat((List) schema.getEnum(), contains("AB", "C-D", "E.F", "")); } } diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiResponse.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiResponse.java index 58e1ebeb77f..e39b3bbf858 100644 --- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiResponse.java +++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiResponse.java @@ -21,7 +21,9 @@ import org.apache.servicecomb.swagger.generator.core.model.SwaggerOperations; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; import io.swagger.v3.oas.annotations.headers.Header; import io.swagger.v3.oas.annotations.media.Content; @@ -30,11 +32,18 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import jakarta.ws.rs.core.MediaType; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class TestApiResponse { - static SwaggerOperations swaggerOperations = SwaggerOperations.generate(ApiResponseAnnotation.class); + + SwaggerOperations swaggerOperations; + + @BeforeAll + public void setUp() { + swaggerOperations = SwaggerOperations.generate(ApiResponseAnnotation.class); + } @AfterAll - public static void teardown() { + public void tearDown() { swaggerOperations = null; } diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestOperationGenerator.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestOperationGenerator.java index f238e91ff34..b46b9bb8327 100644 --- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestOperationGenerator.java +++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestOperationGenerator.java @@ -27,7 +27,9 @@ import org.hamcrest.MatcherAssert; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.Operation; @@ -39,11 +41,17 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class TestOperationGenerator { - static SwaggerOperations swaggerOperations = SwaggerOperations.generate(TestClass.class); + SwaggerOperations swaggerOperations; + + @BeforeAll + public void setUp() { + swaggerOperations = SwaggerOperations.generate(TestClass.class); + } @AfterAll - public static void teardown() { + public void tearDown() { swaggerOperations = null; } diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestSwaggerUtils.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestSwaggerUtils.java index 6a138dc42f1..7611a3f80a7 100644 --- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestSwaggerUtils.java +++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestSwaggerUtils.java @@ -28,11 +28,14 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.logging.Logger; import org.apache.servicecomb.foundation.common.utils.ReflectUtils; import org.apache.servicecomb.swagger.SwaggerUtils; import org.apache.servicecomb.swagger.generator.SwaggerConst; import org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils; +import org.apache.servicecomb.swagger.generator.core.pojo.TestTypeClass; +import org.apache.servicecomb.swagger.generator.core.pojo.TestTypeRecord; import org.apache.servicecomb.swagger.generator.core.pojo.TestType1; import org.apache.servicecomb.swagger.generator.core.pojo.TestType2; import org.apache.servicecomb.swagger.generator.core.schema.RepeatOperation; @@ -50,6 +53,7 @@ @SuppressWarnings("rawtypes") public class TestSwaggerUtils { + Logger LOGGER = Logger.getLogger(TestSwaggerUtils.class.getName()); @Test public void testSchemaMethod() { @@ -117,12 +121,24 @@ private static class AllTypeTest2 { Map t3; TestType2[] t4; + + } + + private static class AllTypeTest3{ + TestTypeRecord t5; + } + private static class AllTypeTest4{ + TestTypeClass t5; } @Test public void testAddDefinitions() { - Field[] fields1 = AllTypeTest1.class.getDeclaredFields(); - Field[] fields2 = AllTypeTest2.class.getDeclaredFields(); + testAllType(AllTypeTest1.class, AllTypeTest2.class); + } + + private void testAllType(Class clazz1, Class clazz2) { + Field[] fields1 = clazz1.getDeclaredFields(); + Field[] fields2 = clazz2.getDeclaredFields(); for (Field value : fields1) { for (Field field : fields2) { if (value.isSynthetic() || field.isSynthetic()) { @@ -132,12 +148,18 @@ public void testAddDefinitions() { testExcep(value.getGenericType(), field.getGenericType()); fail("IllegalArgumentException expected"); } catch (IllegalArgumentException e) { + LOGGER.warning(value.getGenericType() + " " + field.getGenericType() + " " + e.getMessage()); MatcherAssert.assertThat(e.getMessage(), containsString("duplicate param model:")); } } } } + @Test + public void testAddDefinitionsWithRecord() { + testAllType(AllTypeTest3.class, AllTypeTest4.class); + } + private void testExcep(Type f1, Type f2) { OpenAPI swagger = new OpenAPI(); SwaggerUtils.resolveTypeSchemas(swagger, f1); @@ -161,5 +183,13 @@ public void test_resolve_type_schemas_correct() { // should be ObjectSchema but swagger is not. //

 Assertions.assertTrue(schema instanceof ObjectSchema) 
Assertions.assertEquals("object", schema.getType()); + + openAPI = new OpenAPI(); + schema = SwaggerUtils.getSchema(openAPI, SwaggerUtils.resolveTypeSchemas(openAPI, TestTypeClass.class)); // resolve reference + Assertions.assertEquals("object", schema.getType()); + + openAPI = new OpenAPI(); + schema = SwaggerUtils.getSchema(openAPI, SwaggerUtils.resolveTypeSchemas(openAPI, TestTypeRecord.class)); // resolve reference + Assertions.assertEquals("object", schema.getType()); } } diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestTypeClass.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestTypeClass.java new file mode 100644 index 00000000000..b00a4433480 --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestTypeClass.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.swagger.generator.core.pojo; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(name = "YYY") +public class TestTypeClass { + @Schema(description = "language") + private TestTypeEnumLang testTypeEnumLang; + + public TestTypeEnumLang getTestTypeEnumLang() { + return testTypeEnumLang; + } + + public void setTestTypeEnumLang(TestTypeEnumLang testTypeEnumLang) { + this.testTypeEnumLang = testTypeEnumLang; + } +} diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestTypeEnumLang.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestTypeEnumLang.java new file mode 100644 index 00000000000..515f45c7bb1 --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestTypeEnumLang.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.swagger.generator.core.pojo; + +public enum TestTypeEnumLang { + JAVA, CHINESE, UNKNOWN; +} diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestTypeRecord.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestTypeRecord.java new file mode 100644 index 00000000000..c61cc0913eb --- /dev/null +++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/pojo/TestTypeRecord.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.swagger.generator.core.pojo; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(name = "YYY") +public record TestTypeRecord( + @Schema(description = "language") TestTypeEnumLang testTypeEnumLang) { +} diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessorTest.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessorTest.java index e164a97cadf..fdc3cea273e 100644 --- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessorTest.java +++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessorTest.java @@ -28,7 +28,9 @@ import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; @@ -41,11 +43,17 @@ import jakarta.validation.constraints.NotNull; import jakarta.ws.rs.core.MediaType; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class OperationMethodAnnotationProcessorTest { - static SwaggerOperations swaggerOperations = SwaggerOperations.generate(TestClass.class); + SwaggerOperations swaggerOperations; + + @BeforeAll + public void setUp() { + swaggerOperations = SwaggerOperations.generate(TestClass.class); + } @AfterAll - public static void teardown() { + public void tearDown() { swaggerOperations = null; } diff --git a/swagger/swagger-generator/generator-jaxrs/pom.xml b/swagger/swagger-generator/generator-jaxrs/pom.xml index 65f64741644..1a82b059f8a 100644 --- a/swagger/swagger-generator/generator-jaxrs/pom.xml +++ b/swagger/swagger-generator/generator-jaxrs/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb swagger-generator - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT swagger-generator-jaxrs Java Chassis::Swagger::Generator::Jaxrs diff --git a/swagger/swagger-generator/generator-spring-data/pom.xml b/swagger/swagger-generator/generator-spring-data/pom.xml index 75ffc8b5b79..13c8923cd57 100644 --- a/swagger/swagger-generator/generator-spring-data/pom.xml +++ b/swagger/swagger-generator/generator-spring-data/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb swagger-generator - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/swagger/swagger-generator/generator-springmvc/pom.xml b/swagger/swagger-generator/generator-springmvc/pom.xml index 900e1bee9e2..c4225f11a96 100644 --- a/swagger/swagger-generator/generator-springmvc/pom.xml +++ b/swagger/swagger-generator/generator-springmvc/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb swagger-generator - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT swagger-generator-springmvc Java Chassis::Swagger::Generator::Spring MVC diff --git a/swagger/swagger-generator/pom.xml b/swagger/swagger-generator/pom.xml index 2c9c8298913..e9a03a9c579 100644 --- a/swagger/swagger-generator/pom.xml +++ b/swagger/swagger-generator/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb swagger - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT swagger-generator Java Chassis::Swagger::Generator diff --git a/swagger/swagger-invocation/invocation-core/pom.xml b/swagger/swagger-invocation/invocation-core/pom.xml index 4481b478f77..20897dafd3a 100644 --- a/swagger/swagger-invocation/invocation-core/pom.xml +++ b/swagger/swagger-invocation/invocation-core/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb swagger-invocation - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT swagger-invocation-core Java Chassis::Swagger::Invocation::Core diff --git a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/CommonExceptionDataTest.java b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/CommonExceptionDataTest.java index 39a071f1f48..c12f149b825 100644 --- a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/CommonExceptionDataTest.java +++ b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/CommonExceptionDataTest.java @@ -20,6 +20,8 @@ import static com.google.common.collect.ImmutableMap.of; import static org.assertj.core.api.Assertions.assertThat; +import java.util.Map; + import org.junit.jupiter.api.Test; import io.vertx.core.json.Json; @@ -36,7 +38,11 @@ void should_not_include_code_in_json_when_code_is_null() { void should_include_code_in_json_when_code_is_not_null() { CommonExceptionData data = new CommonExceptionData("code", "msg"); - assertThat(Json.encode(data)).isEqualTo("{\"code\":\"code\",\"message\":\"msg\"}"); + String json = Json.encode(data); + @SuppressWarnings("unchecked") + Map obj = Json.decodeValue(json, Map.class); + + assertThat(obj).containsEntry("code", "code").containsEntry("message", "msg").hasSize(2); } @Test diff --git a/swagger/swagger-invocation/invocation-jaxrs/pom.xml b/swagger/swagger-invocation/invocation-jaxrs/pom.xml index 1301c376ff5..50d12dd243f 100644 --- a/swagger/swagger-invocation/invocation-jaxrs/pom.xml +++ b/swagger/swagger-invocation/invocation-jaxrs/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb swagger-invocation - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT swagger-invocation-jaxrs Java Chassis::Swagger::Invocation::JAXRS diff --git a/swagger/swagger-invocation/invocation-springmvc/pom.xml b/swagger/swagger-invocation/invocation-springmvc/pom.xml index afd3c3864d8..5ae28883576 100644 --- a/swagger/swagger-invocation/invocation-springmvc/pom.xml +++ b/swagger/swagger-invocation/invocation-springmvc/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb swagger-invocation - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT swagger-invocation-springmvc Java Chassis::Swagger::Invocation::Spring MVC diff --git a/swagger/swagger-invocation/invocation-validator/pom.xml b/swagger/swagger-invocation/invocation-validator/pom.xml index 921a971f381..cf0f46c7f4f 100644 --- a/swagger/swagger-invocation/invocation-validator/pom.xml +++ b/swagger/swagger-invocation/invocation-validator/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb swagger-invocation - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT swagger-invocation-validator Java Chassis::Swagger::Invocation::Validator diff --git a/swagger/swagger-invocation/pom.xml b/swagger/swagger-invocation/pom.xml index 8943c4a0bd0..00f83a03fc4 100644 --- a/swagger/swagger-invocation/pom.xml +++ b/swagger/swagger-invocation/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb swagger - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT swagger-invocation Java Chassis::Swagger::Invocation diff --git a/tracing/pom.xml b/tracing/pom.xml index 8359080d307..7ffde2fbc3a 100644 --- a/tracing/pom.xml +++ b/tracing/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default 4.0.0 diff --git a/tracing/tracing-common/pom.xml b/tracing/tracing-common/pom.xml index 2201f246867..f03ecbb2b04 100644 --- a/tracing/tracing-common/pom.xml +++ b/tracing/tracing-common/pom.xml @@ -22,7 +22,7 @@ tracing org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/tracing/tracing-zipkin/pom.xml b/tracing/tracing-zipkin/pom.xml index 913939f4a0c..e5755729748 100644 --- a/tracing/tracing-zipkin/pom.xml +++ b/tracing/tracing-zipkin/pom.xml @@ -22,7 +22,7 @@ tracing org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/transports/pom.xml b/transports/pom.xml index 36d33af31fc..13439c0ffdc 100644 --- a/transports/pom.xml +++ b/transports/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb java-chassis-parent - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT ../parents/default transports diff --git a/transports/transport-common/pom.xml b/transports/transport-common/pom.xml index 1ebd172e2c2..00c1ae33c73 100644 --- a/transports/transport-common/pom.xml +++ b/transports/transport-common/pom.xml @@ -21,7 +21,7 @@ transports org.apache.servicecomb - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT 4.0.0 diff --git a/transports/transport-common/src/test/java/org/apache/servicecomb/transport/common/TestTransportConfigUtils.java b/transports/transport-common/src/test/java/org/apache/servicecomb/transport/common/TestTransportConfigUtils.java index 16c16adc89e..05351e62351 100644 --- a/transports/transport-common/src/test/java/org/apache/servicecomb/transport/common/TestTransportConfigUtils.java +++ b/transports/transport-common/src/test/java/org/apache/servicecomb/transport/common/TestTransportConfigUtils.java @@ -60,7 +60,7 @@ public void readVerticleCount_old_exist() { Assertions.assertEquals(10, TransportConfigUtils.readVerticleCount(key, deprecatedKey)); Assertions.assertEquals("thread-count is ambiguous, and deprecated, recommended to use verticle-count.", collector.getEvent(0).getMessage().getFormattedMessage()); - collector.teardown(); + collector.tearDown(); } @Test @@ -79,7 +79,7 @@ int availableProcessors() { Assertions.assertEquals(7, TransportConfigUtils.readVerticleCount(key, deprecatedKey)); Assertions.assertEquals("verticle-count not defined, set to 7.", collector.getLastEvents().getMessage().getFormattedMessage()); - collector.teardown(); + collector.tearDown(); } @Test @@ -106,6 +106,6 @@ int availableProcessors() { Assertions.assertEquals("verticle-count not defined, set to 8.", collector.getLastEvents().getMessage().getFormattedMessage()); - collector.teardown(); + collector.tearDown(); } } diff --git a/transports/transport-highway/pom.xml b/transports/transport-highway/pom.xml index fc921c3a642..d722eb7aa23 100644 --- a/transports/transport-highway/pom.xml +++ b/transports/transport-highway/pom.xml @@ -21,7 +21,7 @@ org.apache.servicecomb transports - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT transport-highway Java Chassis::Transports::Hightway diff --git a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/HighwayServerCodecFilterTest.java b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/HighwayServerCodecFilterTest.java index a9356e3384d..46352690c95 100644 --- a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/HighwayServerCodecFilterTest.java +++ b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/HighwayServerCodecFilterTest.java @@ -45,11 +45,12 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import org.skyscreamer.jsonassert.JSONAssert; import org.springframework.core.env.Environment; import io.vertx.core.MultiMap; import io.vertx.core.buffer.Buffer; -import io.vertx.core.file.impl.FileResolverImpl; +import io.vertx.core.impl.SysProps; import io.vertx.core.json.Json; import mockit.Expectations; import mockit.Mocked; @@ -95,7 +96,7 @@ public void setUp() { long.class, DEFAULT_TURN_DOWN_STATUS_WAIT_SEC)).thenReturn(DEFAULT_TURN_DOWN_STATUS_WAIT_SEC); Mockito.when(environment.getProperty("servicecomb.transport.eventloop.size", int.class, -1)) .thenReturn(-1); - Mockito.when(environment.getProperty(FileResolverImpl.DISABLE_CP_RESOLVING_PROP_NAME, boolean.class, true)) + Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true)) .thenReturn(true); LegacyPropertyFactory.setEnvironment(environment); @@ -146,9 +147,10 @@ public void should_convert_exception_to_response_when_decode_request_failed() Response response = codecFilter.onFilter(invocation, nextNode).get(); assertThat(response.getStatus()).isEqualTo(INTERNAL_SERVER_ERROR); - assertThat(Json.encode(((InvocationException) response.getResult()).getErrorData())) - .isEqualTo("{\"code\":\"SCB.50000000\",\"message\":\"Unexpected " - + "exception when processing null. encode request failed\"}"); + + JSONAssert.assertEquals(Json.encode(((InvocationException) response.getResult()).getErrorData()), + "{\"code\":\"SCB.50000000\",\"message\":\"Unexpected " + + "exception when processing null. encode request failed\"}", false); } private void success_invocation() throws InterruptedException, ExecutionException { diff --git a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayCodec.java b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayCodec.java deleted file mode 100644 index 9de05d4c49e..00000000000 --- a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayCodec.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.servicecomb.transport.highway; - -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; - -import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf; -import org.apache.servicecomb.codec.protobuf.definition.RequestRootDeserializer; -import org.apache.servicecomb.codec.protobuf.definition.RequestRootSerializer; -import org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer; -import org.apache.servicecomb.core.Endpoint; -import org.apache.servicecomb.core.Invocation; -import org.apache.servicecomb.core.definition.MicroserviceMeta; -import org.apache.servicecomb.core.definition.OperationMeta; -import org.apache.servicecomb.core.definition.SchemaMeta; -import org.apache.servicecomb.foundation.vertx.server.TcpParser; -import org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream; -import org.apache.servicecomb.transport.highway.message.RequestHeader; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.jupiter.api.Assertions; -import org.mockito.Mockito; - -import io.netty.buffer.ByteBuf; -import io.vertx.core.buffer.Buffer; -import mockit.Mocked; - -@SuppressWarnings({"unchecked", "rawtypes"}) -public class TestHighwayCodec { - private OperationProtobuf operationProtobuf = null; - - private Buffer bodyBuffer = null; - - private RequestRootSerializer requestSerializer = null; - - private RequestRootDeserializer requestRootDeserializer = null; - - private SchemaMeta schemaMeta = null; - - private OperationMeta operationMeta = null; - - private MicroserviceMeta microserviceMeta = null; - - private ByteBuf lByteBuf = null; - - private ByteBuffer nioBuffer = null; - - private Invocation invocation = null; - - @BeforeClass - public static void setupClass() { - } - - @Before - public void setUp() { - - operationProtobuf = Mockito.mock(OperationProtobuf.class); - - bodyBuffer = Mockito.mock(Buffer.class); - - requestSerializer = Mockito.mock(RequestRootSerializer.class); - - requestRootDeserializer = Mockito.mock(RequestRootDeserializer.class); - - schemaMeta = Mockito.mock(SchemaMeta.class); - - operationMeta = Mockito.mock(OperationMeta.class); - - microserviceMeta = Mockito.mock(MicroserviceMeta.class); - - lByteBuf = Mockito.mock(ByteBuf.class); - - nioBuffer = Mockito.mock(ByteBuffer.class); - - invocation = Mockito.mock(Invocation.class); - } - - @After - public void tearDown() { - - operationProtobuf = null; - - bodyBuffer = null; - - requestSerializer = null; - - schemaMeta = null; - - operationMeta = null; - - lByteBuf = null; - - nioBuffer = null; - - invocation = null; - } - - - @Test - public void test_decode_request_successful_and_not_copy_header(@Mocked Endpoint endpoint) throws Exception { - // test decode request not thrown exception and not copy header - // header should copied before invocation start. - commonMock(); - - Invocation invocation = new Invocation(endpoint, operationMeta, null); - - invocation.addContext("X-B3-traceId", "test1"); - Assertions.assertEquals("test1", invocation.getContext("X-B3-traceId")); - - RequestHeader headers = new RequestHeader(); - Map context = new HashMap<>(); - headers.setContext(context); - HighwayCodec.decodeRequest(invocation, headers, operationProtobuf, bodyBuffer); - Assertions.assertEquals("test1", invocation.getContext("X-B3-traceId")); - - context.put("X-B3-traceId", "test2"); - HighwayCodec.decodeRequest(invocation, headers, operationProtobuf, bodyBuffer); - Assertions.assertEquals("test1", invocation.getContext("X-B3-traceId")); - } - - @Test - public void testEncodeResponse() { - boolean status = true; - ResponseRootSerializer bodySchema = Mockito.mock(ResponseRootSerializer.class); - try { - commonMock(); - Object data = new Object(); - Mockito.when(bodySchema.serialize(data)).thenReturn(new byte[0]); - HighwayCodec.encodeResponse(23432142, null, bodySchema, data); - } catch (Exception e) { - e.printStackTrace(); - status = false; - } - Assertions.assertTrue(status); - } - - @Test - public void testEncodeRequest() { - boolean status = true; - try { - commonMock(); - Map args = new HashMap<>(0); - Mockito.when(invocation.getInvocationArguments()).thenReturn(args); - Mockito.when(requestSerializer.serialize(args)).thenReturn(new byte[0]); - TcpOutputStream os = HighwayCodec.encodeRequest(0, invocation, operationProtobuf); - Assertions.assertNotNull(os); - Assertions.assertArrayEquals(TcpParser.TCP_MAGIC, os.getBuffer().getBytes(0, 7)); - } catch (Exception e) { - e.printStackTrace(); - status = false; - } - Assertions.assertTrue(status); - } - - private void commonMock() { - Mockito.when(operationProtobuf.getRequestRootSerializer()).thenReturn(requestSerializer); - Mockito.when(operationProtobuf.getRequestRootDeserializer()).thenReturn(requestRootDeserializer); - Mockito.when(bodyBuffer.getByteBuf()).thenReturn(lByteBuf); - Mockito.when(bodyBuffer.getBytes()).thenReturn(new byte[0]); - Mockito.when(lByteBuf.nioBuffer()).thenReturn(nioBuffer); - - Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta); - Mockito.when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta); - } -} diff --git a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayTransport.java b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayTransport.java index fe387de8073..18d674f00f0 100644 --- a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayTransport.java +++ b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayTransport.java @@ -36,7 +36,7 @@ import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; -import io.vertx.core.file.impl.FileResolverImpl; +import io.vertx.core.impl.SysProps; public class TestHighwayTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TestHighwayTransport.class); @@ -70,7 +70,7 @@ public void setUp() { .thenReturn(-1); Mockito.when(environment.getProperty("servicecomb.transport.eventloop.size", int.class, -1)) .thenReturn(-1); - Mockito.when(environment.getProperty(FileResolverImpl.DISABLE_CP_RESOLVING_PROP_NAME, boolean.class, true)) + Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true)) .thenReturn(true); LegacyPropertyFactory.setEnvironment(environment); } diff --git a/transports/transport-rest/pom.xml b/transports/transport-rest/pom.xml index 657300ef185..933e7c8858c 100644 --- a/transports/transport-rest/pom.xml +++ b/transports/transport-rest/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb transports - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT transport-rest Java Chassis::Transports::Rest diff --git a/transports/transport-rest/transport-rest-client/pom.xml b/transports/transport-rest/transport-rest-client/pom.xml index 5f6e49772ed..49175b2140a 100644 --- a/transports/transport-rest/transport-rest-client/pom.xml +++ b/transports/transport-rest/transport-rest-client/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb transport-rest - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT transport-rest-client Java Chassis::Transports::Rest::Client diff --git a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/HttpTransportHttpClientOptionsSPI.java b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/HttpTransportHttpClientOptionsSPI.java index 8ff112a16cb..1091167ceed 100644 --- a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/HttpTransportHttpClientOptionsSPI.java +++ b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/HttpTransportHttpClientOptionsSPI.java @@ -22,6 +22,7 @@ import io.vertx.core.VertxOptions; import io.vertx.core.http.HttpClientOptions; import io.vertx.core.http.HttpVersion; +import io.vertx.core.http.PoolOptions; public class HttpTransportHttpClientOptionsSPI implements HttpClientOptionsSPI { public static final String CLIENT_NAME = "http-transport-client"; @@ -136,12 +137,12 @@ public int getHttp2MultiplexingLimit() { @Override public int getHttp2MaxPoolSize() { - return HttpClientOptions.DEFAULT_HTTP2_MAX_POOL_SIZE; + return PoolOptions.DEFAULT_HTTP2_MAX_POOL_SIZE; } @Override public boolean isUseAlpn() { - return HttpClientOptions.DEFAULT_USE_ALPN; + return !HttpClientOptions.DEFAULT_ALPN_VERSIONS.isEmpty(); } @Override diff --git a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientEncoder.java b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientEncoder.java index 7a9b4330ef5..cc16c832f08 100644 --- a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientEncoder.java +++ b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientEncoder.java @@ -41,8 +41,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; import io.vertx.core.buffer.Buffer; import io.vertx.core.http.HttpClientRequest; import jakarta.servlet.http.Part; @@ -151,22 +149,19 @@ protected void writeUrlEncodedForm(Map formMap) throws Exception } protected Buffer genUrlEncodedFormBuffer(Map formMap) throws Exception { - // 2x faster than UriComponentsBuilder - ByteBuf byteBuf = Unpooled.buffer(RestClientEncoder.FORM_BUFFER_SIZE); + Buffer buffer = Buffer.buffer(RestClientEncoder.FORM_BUFFER_SIZE); for (Entry entry : formMap.entrySet()) { - writeCharSequence(byteBuf, entry.getKey()); - byteBuf.writeByte('='); + writeCharSequence(buffer, entry.getKey()); + buffer.appendByte(((byte) '=')); String value = QueryCodec.convertToString(entry.getValue()); - String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.name()); - writeCharSequence(byteBuf, encodedValue); + String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8); + writeCharSequence(buffer, encodedValue); - byteBuf.markWriterIndex(); - byteBuf.writeByte('&'); + buffer.appendByte(((byte) '&')); } - byteBuf.resetWriterIndex(); - return Buffer.buffer(byteBuf); + return buffer; } protected void writeChunkedForm(Map formMap) throws Exception { @@ -184,65 +179,65 @@ protected void writeChunkedForm(Map formMap) throws Exception { } protected Buffer genChunkedFormBuffer(Map formMap, String boundary) throws Exception { - ByteBuf byteBuf = Unpooled.buffer(RestClientEncoder.FORM_BUFFER_SIZE); + Buffer buffer = Buffer.buffer(RestClientEncoder.FORM_BUFFER_SIZE); for (Entry entry : formMap.entrySet()) { Object content = entry.getValue(); if (content instanceof List) { for (Object item : ((List) content)) { - writeFormData(byteBuf, boundary, entry.getKey(), item); + writeFormData(buffer, boundary, entry.getKey(), item); } } else { - writeFormData(byteBuf, boundary, entry.getKey(), entry.getValue()); + writeFormData(buffer, boundary, entry.getKey(), entry.getValue()); } } - return Buffer.buffer(byteBuf); + return buffer; } - private void writeFormData(ByteBuf byteBuf, String boundary, String key, Object data) throws Exception { - writeCharSequence(byteBuf, "\r\n--"); - writeCharSequence(byteBuf, boundary); - writeCharSequence(byteBuf, "\r\nContent-Disposition: form-data; name=\""); - writeCharSequence(byteBuf, key); - writeCharSequence(byteBuf, "\"\r\n\r\n"); + private void writeFormData(Buffer buffer, String boundary, String key, Object data) throws Exception { + writeCharSequence(buffer, "\r\n--"); + writeCharSequence(buffer, boundary); + writeCharSequence(buffer, "\r\nContent-Disposition: form-data; name=\""); + writeCharSequence(buffer, key); + writeCharSequence(buffer, "\"\r\n\r\n"); String value = QueryCodec.convertToString(data); - writeCharSequence(byteBuf, value); + writeCharSequence(buffer, value); } } - protected static void writeCharSequence(ByteBuf byteBuf, String value) { - byteBuf.writeCharSequence(value, StandardCharsets.UTF_8); + protected static void writeCharSequence(Buffer buffer, String value) { + buffer.appendString(value, "UTF-8"); } public static Buffer genFileBoundaryBuffer(Part part, String name, String boundary) { - ByteBuf byteBuf = Unpooled.buffer(); + Buffer buffer = Buffer.buffer(RestClientEncoder.FORM_BUFFER_SIZE); - writeCharSequence(byteBuf, "\r\n--"); - writeCharSequence(byteBuf, boundary); - writeCharSequence(byteBuf, "\r\nContent-Disposition: form-data; name=\""); - writeCharSequence(byteBuf, name); - writeCharSequence(byteBuf, "\"; filename=\""); - writeCharSequence(byteBuf, String.valueOf(part.getSubmittedFileName())); - writeCharSequence(byteBuf, "\"\r\n"); + writeCharSequence(buffer, "\r\n--"); + writeCharSequence(buffer, boundary); + writeCharSequence(buffer, "\r\nContent-Disposition: form-data; name=\""); + writeCharSequence(buffer, name); + writeCharSequence(buffer, "\"; filename=\""); + writeCharSequence(buffer, String.valueOf(part.getSubmittedFileName())); + writeCharSequence(buffer, "\"\r\n"); - writeCharSequence(byteBuf, "Content-Type: "); - writeCharSequence(byteBuf, part.getContentType()); - writeCharSequence(byteBuf, "\r\n"); + writeCharSequence(buffer, "Content-Type: "); + writeCharSequence(buffer, part.getContentType()); + writeCharSequence(buffer, "\r\n"); - writeCharSequence(byteBuf, "Content-Transfer-Encoding: binary\r\n"); + writeCharSequence(buffer, "Content-Transfer-Encoding: binary\r\n"); - writeCharSequence(byteBuf, "\r\n"); + writeCharSequence(buffer, "\r\n"); - return Buffer.buffer(byteBuf); + return buffer; } public static Buffer genBoundaryEndBuffer(String boundary) { - ByteBuf byteBuf = Unpooled.buffer(); + Buffer buffer = Buffer.buffer(RestClientEncoder.FORM_BUFFER_SIZE); - writeCharSequence(byteBuf, "\r\n--"); - writeCharSequence(byteBuf, boundary); - writeCharSequence(byteBuf, "--\r\n"); + writeCharSequence(buffer, "\r\n--"); + writeCharSequence(buffer, boundary); + writeCharSequence(buffer, "--\r\n"); - return Buffer.buffer(byteBuf); + return buffer; } } diff --git a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientSender.java b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientSender.java index bb61ccabba4..b737736c243 100644 --- a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientSender.java +++ b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientSender.java @@ -83,7 +83,7 @@ protected void runInVertxContext() { } protected CompletableFuture sendInVertxContext() { - httpClientRequest.setTimeout(invocation.getOperationMeta().getConfig().getMsRequestTimeout()); + httpClientRequest.idleTimeout(invocation.getOperationMeta().getConfig().getMsRequestTimeout()); Multimap uploads = requestParameters.getUploads(); if (uploads == null) { diff --git a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/TransportClientConfig.java b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/TransportClientConfig.java index ff18a5a7ba1..e1f2c6042d1 100644 --- a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/TransportClientConfig.java +++ b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/TransportClientConfig.java @@ -21,6 +21,7 @@ import org.apache.servicecomb.transport.common.TransportConfigUtils; import io.vertx.core.http.HttpClientOptions; +import io.vertx.core.http.PoolOptions; public final class TransportClientConfig { private static final int DEFAULT_IDLE_TIME_OUT = 150; @@ -38,7 +39,7 @@ public static int getThreadCount() { public static int getHttp2ConnectionMaxPoolSize() { return LegacyPropertyFactory.getIntProperty("servicecomb.rest.client.http2.maxPoolSize", - HttpClientOptions.DEFAULT_HTTP2_MAX_POOL_SIZE); + PoolOptions.DEFAULT_HTTP2_MAX_POOL_SIZE); } public static int getHttp2MultiplexingLimit() { @@ -57,7 +58,7 @@ public static boolean isHttp2TransportClientEnabled() { public static int getConnectionMaxPoolSize() { return LegacyPropertyFactory.getIntProperty("servicecomb.rest.client.connection.maxPoolSize", - HttpClientOptions.DEFAULT_MAX_POOL_SIZE); + PoolOptions.DEFAULT_MAX_POOL_SIZE); } public static int getHttp2ConnectionIdleTimeoutInSeconds() { @@ -94,7 +95,7 @@ public static int getHttp2ConnectionKeepAliveTimeoutInSeconds() { public static boolean getConnectionCompression() { return LegacyPropertyFactory .getBooleanProperty("servicecomb.rest.client.connection.compression", - HttpClientOptions.DEFAULT_TRY_USE_COMPRESSION); + HttpClientOptions.DEFAULT_DECOMPRESSION_SUPPORTED); } public static int getMaxHeaderSize() { @@ -105,7 +106,7 @@ public static int getMaxHeaderSize() { public static int getMaxWaitQueueSize() { return LegacyPropertyFactory .getIntProperty("servicecomb.rest.client.maxWaitQueueSize", - HttpClientOptions.DEFAULT_MAX_WAIT_QUEUE_SIZE); + PoolOptions.DEFAULT_MAX_WAIT_QUEUE_SIZE); } public static boolean isHttpTransportClientEnabled() { diff --git a/transports/transport-rest/transport-rest-servlet/pom.xml b/transports/transport-rest/transport-rest-servlet/pom.xml index 0245a6001b3..0bdac6777ef 100644 --- a/transports/transport-rest/transport-rest-servlet/pom.xml +++ b/transports/transport-rest/transport-rest-servlet/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb transport-rest - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT transport-rest-servlet Java Chassis::Transports::Rest::Servlet diff --git a/transports/transport-rest/transport-rest-servlet/src/test/java/org/apache/servicecomb/transport/rest/servlet/TestRestServlet.java b/transports/transport-rest/transport-rest-servlet/src/test/java/org/apache/servicecomb/transport/rest/servlet/TestRestServlet.java index 168efb4d087..9c94e49d58c 100644 --- a/transports/transport-rest/transport-rest-servlet/src/test/java/org/apache/servicecomb/transport/rest/servlet/TestRestServlet.java +++ b/transports/transport-rest/transport-rest-servlet/src/test/java/org/apache/servicecomb/transport/rest/servlet/TestRestServlet.java @@ -30,7 +30,7 @@ import org.mockito.Mockito; import org.springframework.core.env.Environment; -import io.vertx.core.file.impl.FileResolverImpl; +import io.vertx.core.impl.SysProps; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -51,7 +51,7 @@ public void setUp() { .thenReturn(0); Mockito.when(environment.getProperty("servicecomb.transport.eventloop.size", int.class, -1)) .thenReturn(-1); - Mockito.when(environment.getProperty(FileResolverImpl.DISABLE_CP_RESOLVING_PROP_NAME, boolean.class, true)) + Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true)) .thenReturn(true); LegacyPropertyFactory.setEnvironment(environment); restservlet = new RestServlet(); diff --git a/transports/transport-rest/transport-rest-servlet/src/test/java/org/apache/servicecomb/transport/rest/servlet/TestServletRestTransport.java b/transports/transport-rest/transport-rest-servlet/src/test/java/org/apache/servicecomb/transport/rest/servlet/TestServletRestTransport.java index d9d396fe27f..6875965a109 100644 --- a/transports/transport-rest/transport-rest-servlet/src/test/java/org/apache/servicecomb/transport/rest/servlet/TestServletRestTransport.java +++ b/transports/transport-rest/transport-rest-servlet/src/test/java/org/apache/servicecomb/transport/rest/servlet/TestServletRestTransport.java @@ -32,7 +32,7 @@ import org.mockito.Mockito; import org.springframework.core.env.Environment; -import io.vertx.core.file.impl.FileResolverImpl; +import io.vertx.core.impl.SysProps; import mockit.Expectations; public class TestServletRestTransport { @@ -48,7 +48,7 @@ public void setUp() { .thenReturn(0); Mockito.when(environment.getProperty("servicecomb.transport.eventloop.size", int.class, -1)) .thenReturn(-1); - Mockito.when(environment.getProperty(FileResolverImpl.DISABLE_CP_RESOLVING_PROP_NAME, boolean.class, true)) + Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true)) .thenReturn(true); LegacyPropertyFactory.setEnvironment(environment); transport = new ServletRestTransport(); diff --git a/transports/transport-rest/transport-rest-vertx/pom.xml b/transports/transport-rest/transport-rest-vertx/pom.xml index 6e9ae331dea..7a3475d38dd 100644 --- a/transports/transport-rest/transport-rest-vertx/pom.xml +++ b/transports/transport-rest/transport-rest-vertx/pom.xml @@ -22,7 +22,7 @@ org.apache.servicecomb transport-rest - 3.3.0-SNAPSHOT + 3.4.0-SNAPSHOT transport-rest-vertx Java Chassis::Transports::Rest::Vertx diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestBodyHandler.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestBodyHandler.java index 6492e77e87c..cc74e6d0a8a 100644 --- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestBodyHandler.java +++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestBodyHandler.java @@ -232,11 +232,11 @@ private class BHandler implements Handler { Buffer body; - boolean failed; + volatile boolean failed; final AtomicInteger uploadCount = new AtomicInteger(); - boolean ended; + volatile boolean ended; long uploadSize = 0L; diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java index 7aa346a63c0..70f8e43c765 100644 --- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java +++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java @@ -47,6 +47,7 @@ import io.vertx.core.AbstractVerticle; import io.vertx.core.Context; +import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.core.Promise; import io.vertx.core.Vertx; @@ -244,11 +245,12 @@ private void initDispatcher(Router mainRouter) { } private void startListen(HttpServer server, Promise startPromise) { - server.listen(endpointObject.getPort(), endpointObject.getHostOrIp(), ar -> { - if (ar.succeeded()) { + Future result = server.listen(endpointObject.getPort(), endpointObject.getHostOrIp()); + result.onComplete((s, f) -> { + if (f == null) { LOGGER.info("rest listen success. address={}:{}", endpointObject.getHostOrIp(), - ar.result().actualPort()); + s.actualPort()); startPromise.complete(); return; } @@ -256,8 +258,8 @@ private void startListen(HttpServer server, Promise startPromise) { String msg = String.format("rest listen failed, address=%s:%d", endpointObject.getHostOrIp(), endpointObject.getPort()); - LOGGER.error(msg, ar.cause()); - startPromise.fail(ar.cause()); + LOGGER.error(msg, f); + startPromise.fail(f); }); } diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java index 38f87fba48d..20f83446e57 100644 --- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java +++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java @@ -124,15 +124,13 @@ private void sendFailureRespDeterminedByStatus(RoutingContext context) { .setStatusMessage(Status.INTERNAL_SERVER_ERROR.getReasonPhrase()) .end(wrapResponseBody(Status.INTERNAL_SERVER_ERROR.getReasonPhrase())); } - context.response().close(); } /** * Use routingContext to send failure information in throwable. */ private void sendExceptionByRoutingContext(RoutingContext context, Throwable e) { - if (e instanceof InvocationException) { - InvocationException invocationException = (InvocationException) e; + if (e instanceof InvocationException invocationException) { context.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD) .setStatusCode(invocationException.getStatusCode()).setStatusMessage(invocationException.getReasonPhrase()) .end(wrapResponseBody(invocationException.getReasonPhrase())); @@ -141,7 +139,6 @@ private void sendExceptionByRoutingContext(RoutingContext context, Throwable e) .setStatusCode(Status.INTERNAL_SERVER_ERROR.getStatusCode()) .end(wrapResponseBody(Status.INTERNAL_SERVER_ERROR.getReasonPhrase())); } - context.response().close(); } /** diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/MockHttpServerResponse.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/MockHttpServerResponse.java index 568aab893a2..74a8307262b 100644 --- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/MockHttpServerResponse.java +++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/MockHttpServerResponse.java @@ -17,8 +17,13 @@ package org.apache.servicecomb.transport.rest.vertx; +import java.io.RandomAccessFile; +import java.nio.channels.FileChannel; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + import io.vertx.codegen.annotations.Nullable; -import io.vertx.core.AsyncResult; import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.core.MultiMap; @@ -28,13 +33,7 @@ import io.vertx.core.http.HttpServerResponse; import io.vertx.core.net.HostAndPort; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - class MockHttpServerResponse implements HttpServerResponse { - boolean responseClosed; - boolean responseEnded; Map responseHeader = new HashMap<>(1); @@ -45,11 +44,6 @@ class MockHttpServerResponse implements HttpServerResponse { String responseChunk; - @Override - public void close() { - responseClosed = true; - } - @Override public HttpServerResponse putHeader(String name, String value) { responseHeader.put(name, value); @@ -74,11 +68,6 @@ public Future end() { return Future.succeededFuture(); } - @Override - public void end(Handler> handler) { - - } - @Override public Future end(String chunk) { responseEnded = true; @@ -86,11 +75,6 @@ public Future end(String chunk) { return Future.succeededFuture(); } - @Override - public void end(String s, Handler> handler) { - - } - @Override public HttpServerResponse exceptionHandler(Handler handler) { return null; @@ -101,10 +85,6 @@ public Future write(Buffer data) { return Future.succeededFuture(); } - @Override - public void write(Buffer buffer, Handler> handler) { - } - @Override public HttpServerResponse setWriteQueueMaxSize(int maxSize) { return null; @@ -196,26 +176,23 @@ public HttpServerResponse endHandler(Handler handler) { } @Override - public Future write(String chunk, String enc) { - return Future.succeededFuture(); + public Future writeHead() { + return null; } @Override - public void write(String s, String s1, Handler> handler) { + public Future write(String chunk, String enc) { + return Future.succeededFuture(); } + @Override public Future write(String chunk) { return Future.succeededFuture(); } @Override - public void write(String s, Handler> handler) { - - } - - @Override - public HttpServerResponse writeContinue() { + public Future writeContinue() { return null; } @@ -224,29 +201,17 @@ public Future writeEarlyHints(MultiMap headers) { return Future.succeededFuture(); } - @Override - public void writeEarlyHints(MultiMap headers, Handler> handler) { - } - @Override public Future end(String chunk, String enc) { return Future.succeededFuture(); } - @Override - public void end(String s, String s1, Handler> handler) { - - } @Override public Future end(Buffer chunk) { return Future.succeededFuture(); } - @Override - public void end(Buffer buffer, Handler> handler) { - - } @Override public Future sendFile(String filename, long offset, long length) { @@ -254,8 +219,12 @@ public Future sendFile(String filename, long offset, long length) { } @Override - public HttpServerResponse sendFile(String filename, long offset, long length, - Handler> resultHandler) { + public Future sendFile(FileChannel channel, long offset, long length) { + return null; + } + + @Override + public Future sendFile(RandomAccessFile file, long offset, long length) { return null; } @@ -294,46 +263,18 @@ public int streamId() { return 0; } - @Override - public HttpServerResponse push(HttpMethod method, String host, String path, - Handler> handler) { - return null; - } - - @Override - public HttpServerResponse push(HttpMethod method, String path, MultiMap headers, - Handler> handler) { - return null; - } - - @Override - public HttpServerResponse push(HttpMethod method, String path, Handler> handler) { - return null; - } - - @Override - public HttpServerResponse push(HttpMethod method, String host, String path, MultiMap headers, - Handler> handler) { - return null; - } - @Override public Future push(HttpMethod httpMethod, HostAndPort hostAndPort, String s, MultiMap multiMap) { return null; } @Override - public Future push(HttpMethod method, String host, String path, MultiMap headers) { - return Future.succeededFuture(); - } - - @Override - public boolean reset(long code) { - return false; + public Future reset(long code) { + return null; } @Override - public HttpServerResponse writeCustomFrame(int type, int flags, Buffer payload) { + public Future writeCustomFrame(int type, int flags, Buffer payload) { return null; } diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestRestServerVerticle.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestRestServerVerticle.java index 8df4aa0f1f1..4154cc635c5 100644 --- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestRestServerVerticle.java +++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestRestServerVerticle.java @@ -65,10 +65,10 @@ import io.vertx.core.Handler; import io.vertx.core.Promise; import io.vertx.core.Vertx; -import io.vertx.core.file.impl.FileResolverImpl; import io.vertx.core.http.Http2Settings; import io.vertx.core.http.HttpMethod; import io.vertx.core.http.HttpServerResponse; +import io.vertx.core.impl.SysProps; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.Route; import io.vertx.ext.web.Router; @@ -164,7 +164,7 @@ public void setUp() { .thenReturn(Http2Settings.DEFAULT_ENABLE_PUSH); Mockito.when(environment.getProperty("servicecomb.transport.eventloop.size", int.class, -1)) .thenReturn(-1); - Mockito.when(environment.getProperty(FileResolverImpl.DISABLE_CP_RESOLVING_PROP_NAME, boolean.class, true)) + Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true)) .thenReturn(true); Mockito.when(environment.getProperty(CLIENT_LOG_ENABLED, boolean.class, false)) .thenReturn(false); diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestVertxRestTransport.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestVertxRestTransport.java index c0e2af45da9..fb14f5115de 100644 --- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestVertxRestTransport.java +++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestVertxRestTransport.java @@ -37,7 +37,7 @@ import io.vertx.core.DeploymentOptions; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; -import io.vertx.core.file.impl.FileResolverImpl; +import io.vertx.core.impl.SysProps; import mockit.Expectations; import mockit.Mock; import mockit.MockUp; @@ -69,7 +69,7 @@ public void setUp() { .thenReturn(""); Mockito.when(environment.getProperty("servicecomb.transport.eventloop.size", int.class, -1)) .thenReturn(-1); - Mockito.when(environment.getProperty(FileResolverImpl.DISABLE_CP_RESOLVING_PROP_NAME, boolean.class, true)) + Mockito.when(environment.getProperty(SysProps.DISABLE_FILE_CP_RESOLVING.name, boolean.class, true)) .thenReturn(true); LegacyPropertyFactory.setEnvironment(environment); instance = new VertxRestTransport();