diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index b901097f2..000000000 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2007-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import java.net.*; -import java.io.*; -import java.nio.channels.*; -import java.util.Properties; - -public class MavenWrapperDownloader { - - private static final String WRAPPER_VERSION = "0.5.6"; - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { - String username = System.getenv("MVNW_USERNAME"); - char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); - } - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar index 2cc7d4a55..c1dd12f17 100644 Binary files a/.mvn/wrapper/maven-wrapper.jar and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 642d572ce..b74bf7fcd 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,2 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar diff --git a/CHANGELOG.md b/CHANGELOG.md index 20d44bcd5..0a833fd43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,3 +8,8 @@ - [feat:enhance Feign and RestTemplate and support Polaris monitor.](https://github.com/Tencent/spring-cloud-tencent/pull/447) - [Feature: support spring cloud config data.](https://github.com/Tencent/spring-cloud-tencent/pull/451) - [Optimize feign & rest-template circuit-breaker logic](https://github.com/Tencent/spring-cloud-tencent/pull/454) +- [Feature: Add disposable metadata transfer support](https://github.com/Tencent/spring-cloud-tencent/pull/459) +- [docs:update mvnw.](https://github.com/Tencent/spring-cloud-tencent/pull/476) +- [docs:update configuration metadata.](https://github.com/Tencent/spring-cloud-tencent/pull/474) +- [Feature: delete implement ServiceInstance](https://github.com/Tencent/spring-cloud-tencent/pull/483) +- [test: add loadbalancer unit test](https://github.com/Tencent/spring-cloud-tencent/pull/485) diff --git a/README-zh.md b/README-zh.md index a7c12a03b..a413ca2c8 100644 --- a/README-zh.md +++ b/README-zh.md @@ -85,18 +85,38 @@ Spring Cloud Tencent 所有组件都已上传到 Maven 中央仓库,只需要 ```` -- ### 快速开始 - - [Spring Cloud Tencent 版本管理](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86) - - [Spring Cloud Tencent 服务注册与发现](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Discovery-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - - [Spring Cloud Tencent 配置中心](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Config-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - - [Spring Cloud Tencent 限流](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Rate-Limit-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - - [Spring Cloud Tencent 熔断](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Circuitbreaker-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - - [Spring Cloud Tencent 服务路由](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Router-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - - [Spring Cloud Tencent 标签传递](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Metadata-Transfer-%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97) - -- ### 开发文档 - - [项目概览](https://github.com/Tencent/spring-cloud-tencent/wiki/%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%A7%88) - - [参与共建](https://github.com/Tencent/spring-cloud-tencent/wiki/%E5%8F%82%E4%B8%8E%E5%85%B1%E5%BB%BA) +## 开发入门 + +You can build this project with command: + +```shell +## MacOS or Linux +./mvnw clean package + +## Win +.\mvnw.cmd clean package +``` + +## 文档 + +- 使用文档 + - [Spring Cloud Tencent Version Management](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86) + - [Spring Cloud Tencent Discovery](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Discovery-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) + - [Spring Cloud Tencent Config](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Config-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) + - [Spring Cloud Tencent Rate Limit](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Rate-Limit-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) + - [Spring Cloud Tencent CircuitBreaker](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Circuitbreaker-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) + - [Spring Cloud Tencent Router](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Router-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) + - [Spring Cloud Starter Tencent RPC Enhancement](https://github.com/Tencent/spring-cloud-tencent/wiki/RPC%E5%A2%9E%E5%BC%BA) + - [Spring Cloud Tencent Metadata Transfer](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Metadata-Transfer-%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97) + - [Actuator Endpoint Extension](https://github.com/Tencent/spring-cloud-tencent/wiki/Actuator-Endpoint-%E6%89%A9%E5%B1%95) + +- 最佳实践 + - [Multi-feature environment](https://github.com/Tencent/spring-cloud-tencent/wiki/多特性环境) + - [Multi-registration and multi-discovery](https://github.com/Tencent/spring-cloud-tencent/wiki/Multi-registration-and-multi-discovery) + +- 开发文档 + - [Project Structure Overview](https://github.com/Tencent/spring-cloud-tencent/wiki/%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%A7%88) + - [Participate in co-construction](https://github.com/Tencent/spring-cloud-tencent/wiki/%E5%8F%82%E4%B8%8E%E5%85%B1%E5%BB%BA) ## 交流群 diff --git a/README.md b/README.md index 0603c500a..e4c81cf78 100644 --- a/README.md +++ b/README.md @@ -87,16 +87,36 @@ For example: ```` -- ### Quick Start +## Develop Guide + +You can build this project with command: + +```shell +## MacOS or Linux +./mvnw clean package + +## Win +.\mvnw.cmd clean package +``` + +## Documents + +- Usage Doc - [Spring Cloud Tencent Version Management](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86) - [Spring Cloud Tencent Discovery](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Discovery-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - [Spring Cloud Tencent Config](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Config-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - [Spring Cloud Tencent Rate Limit](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Rate-Limit-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - [Spring Cloud Tencent CircuitBreaker](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Circuitbreaker-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - [Spring Cloud Tencent Router](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Router-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) + - [Spring Cloud Starter Tencent RPC Enhancement](https://github.com/Tencent/spring-cloud-tencent/wiki/RPC%E5%A2%9E%E5%BC%BA) - [Spring Cloud Tencent Metadata Transfer](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Metadata-Transfer-%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97) + - [Actuator Endpoint Extension](https://github.com/Tencent/spring-cloud-tencent/wiki/Actuator-Endpoint-%E6%89%A9%E5%B1%95) + +- Best Practices + - [Multi-feature environment](https://github.com/Tencent/spring-cloud-tencent/wiki/多特性环境) + - [Multi-registration and multi-discovery](https://github.com/Tencent/spring-cloud-tencent/wiki/Multi-registration-and-multi-discovery) -- ### Development Documentation +- Development documentation - [Project Structure Overview](https://github.com/Tencent/spring-cloud-tencent/wiki/%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%A7%88) - [Participate in co-construction](https://github.com/Tencent/spring-cloud-tencent/wiki/%E5%8F%82%E4%B8%8E%E5%85%B1%E5%BB%BA) diff --git a/mvnw b/mvnw index 41c0f0c23..8a8fb2282 100755 --- a/mvnw +++ b/mvnw @@ -8,7 +8,7 @@ # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an @@ -36,6 +36,10 @@ if [ -z "$MAVEN_SKIP_RC" ] ; then + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + if [ -f /etc/mavenrc ] ; then . /etc/mavenrc fi @@ -145,7 +149,7 @@ if [ -z "$JAVACMD" ] ; then JAVACMD="$JAVA_HOME/bin/java" fi else - JAVACMD="`which java`" + JAVACMD="`\\unset -f command; \\command -v java`" fi fi @@ -212,9 +216,9 @@ else echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." fi if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" fi while IFS="=" read key value; do case "$key" in (wrapperUrl) jarUrl="$value"; break ;; @@ -233,9 +237,9 @@ else echo "Found wget ... using wget" fi if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" fi elif command -v curl > /dev/null; then if [ "$MVNW_VERBOSE" = true ]; then @@ -305,6 +309,8 @@ WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain exec "$JAVACMD" \ $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd index 86115719e..1d8ab018e 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -7,7 +7,7 @@ @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM -@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM https://www.apache.org/licenses/LICENSE-2.0 @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an @@ -46,8 +46,8 @@ if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") @REM Execute a user defined script before this one if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre @REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* :skipRcPre @setlocal @@ -120,9 +120,9 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B ) @@ -134,7 +134,7 @@ if exist %WRAPPER_JAR% ( ) ) else ( if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" ) if "%MVNW_VERBOSE%" == "true" ( echo Couldn't find %WRAPPER_JAR%, downloading it ... @@ -158,7 +158,13 @@ if exist %WRAPPER_JAR% ( @REM work with both Windows and non-Windows executions. set MAVEN_CMD_LINE_ARGS=%* -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* if ERRORLEVEL 1 goto error goto end @@ -168,15 +174,15 @@ set ERROR_CODE=1 :end @endlocal & set ERROR_CODE=%ERROR_CODE% -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost @REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" :skipRcPost @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause +if "%MAVEN_BATCH_PAUSE%"=="on" pause -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% -exit /B %ERROR_CODE% +cmd /C exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml index 179477dd6..82546eb5b 100644 --- a/pom.xml +++ b/pom.xml @@ -93,10 +93,10 @@ 2021.0.3 - 2.6.9 + 2.6.10 - 5.3.21 + 5.3.22 0.8.8 diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilter.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilter.java index b8815c51d..957493cad 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilter.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataReactiveFilter.java @@ -39,6 +39,8 @@ import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; +import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUSTOM_DISPOSABLE_METADATA; +import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUSTOM_METADATA; /** * Filter used for storing the metadata from upstream temporarily when web application is @@ -60,27 +62,32 @@ public class DecodeTransferMetadataReactiveFilter implements WebFilter, Ordered // Get metadata string from http header. ServerHttpRequest serverHttpRequest = serverWebExchange.getRequest(); - Map internalTransitiveMetadata = getIntervalTransitiveMetadata(serverHttpRequest); + Map internalTransitiveMetadata = getIntervalMetadata(serverHttpRequest, CUSTOM_METADATA); Map customTransitiveMetadata = CustomTransitiveMetadataResolver.resolve(serverWebExchange); Map mergedTransitiveMetadata = new HashMap<>(); mergedTransitiveMetadata.putAll(internalTransitiveMetadata); mergedTransitiveMetadata.putAll(customTransitiveMetadata); - MetadataContextHolder.init(mergedTransitiveMetadata); + Map internalDisposableMetadata = getIntervalMetadata(serverHttpRequest, CUSTOM_DISPOSABLE_METADATA); + Map mergedDisposableMetadata = new HashMap<>(internalDisposableMetadata); + + MetadataContextHolder.init(mergedTransitiveMetadata, mergedDisposableMetadata); // Save to ServerWebExchange. - serverWebExchange.getAttributes() - .put(MetadataConstant.HeaderName.METADATA_CONTEXT, MetadataContextHolder.get()); + serverWebExchange.getAttributes().put( + MetadataConstant.HeaderName.METADATA_CONTEXT, + MetadataContextHolder.get()); return webFilterChain.filter(serverWebExchange) - .doOnError(throwable -> LOG.error("handle metadata[{}] error.", MetadataContextHolder.get(), throwable)) + .doOnError(throwable -> LOG.error("handle metadata[{}] error.", + MetadataContextHolder.get(), throwable)) .doFinally((type) -> MetadataContextHolder.remove()); } - private Map getIntervalTransitiveMetadata(ServerHttpRequest serverHttpRequest) { + private Map getIntervalMetadata(ServerHttpRequest serverHttpRequest, String headerName) { HttpHeaders httpHeaders = serverHttpRequest.getHeaders(); - String customMetadataStr = httpHeaders.getFirst(MetadataConstant.HeaderName.CUSTOM_METADATA); + String customMetadataStr = httpHeaders.getFirst(headerName); try { if (StringUtils.hasText(customMetadataStr)) { customMetadataStr = URLDecoder.decode(customMetadataStr, UTF_8); diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilter.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilter.java index 20df1dc79..a67563915 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilter.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/DecodeTransferMetadataServletFilter.java @@ -36,10 +36,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; +import org.springframework.lang.NonNull; import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; +import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUSTOM_DISPOSABLE_METADATA; +import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUSTOM_METADATA; /** * Filter used for storing the metadata from upstream temporarily when web application is @@ -53,28 +56,27 @@ public class DecodeTransferMetadataServletFilter extends OncePerRequestFilter { private static final Logger LOG = LoggerFactory.getLogger(DecodeTransferMetadataServletFilter.class); @Override - protected void doFilterInternal(HttpServletRequest httpServletRequest, - HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { - Map internalTransitiveMetadata = getInternalTransitiveMetadata(httpServletRequest); + protected void doFilterInternal(@NonNull HttpServletRequest httpServletRequest, + @NonNull HttpServletResponse httpServletResponse, FilterChain filterChain) + throws ServletException, IOException { + Map internalTransitiveMetadata = getInternalMetadata(httpServletRequest, CUSTOM_METADATA); Map customTransitiveMetadata = CustomTransitiveMetadataResolver.resolve(httpServletRequest); Map mergedTransitiveMetadata = new HashMap<>(); mergedTransitiveMetadata.putAll(internalTransitiveMetadata); mergedTransitiveMetadata.putAll(customTransitiveMetadata); - try { - MetadataContextHolder.init(mergedTransitiveMetadata); + Map internalDisposableMetadata = getInternalMetadata(httpServletRequest, CUSTOM_DISPOSABLE_METADATA); + Map mergedDisposableMetadata = new HashMap<>(internalDisposableMetadata); - filterChain.doFilter(httpServletRequest, httpServletResponse); - } - catch (IOException | ServletException | RuntimeException e) { - throw e; - } + MetadataContextHolder.init(mergedTransitiveMetadata, mergedDisposableMetadata); + + filterChain.doFilter(httpServletRequest, httpServletResponse); } - private Map getInternalTransitiveMetadata(HttpServletRequest httpServletRequest) { + private Map getInternalMetadata(HttpServletRequest httpServletRequest, String headerName) { // Get custom metadata string from http header. - String customMetadataStr = httpServletRequest.getHeader(MetadataConstant.HeaderName.CUSTOM_METADATA); + String customMetadataStr = httpServletRequest.getHeader(headerName); try { if (StringUtils.hasText(customMetadataStr)) { customMetadataStr = URLDecoder.decode(customMetadataStr, UTF_8); diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptor.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptor.java index 3bfefe036..fa63f3df8 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptor.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignInterceptor.java @@ -19,7 +19,7 @@ package com.tencent.cloud.metadata.core; import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; +import java.util.HashMap; import java.util.Map; import com.tencent.cloud.common.constant.MetadataConstant; @@ -33,9 +33,12 @@ import org.slf4j.LoggerFactory; import org.springframework.core.Ordered; import org.springframework.util.CollectionUtils; +import org.springframework.web.client.RestTemplate; import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; +import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUSTOM_DISPOSABLE_METADATA; import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUSTOM_METADATA; +import static java.net.URLEncoder.encode; /** * Interceptor used for adding the metadata in http headers from context when web client @@ -57,16 +60,37 @@ public class EncodeTransferMedataFeignInterceptor implements RequestInterceptor, // get metadata of current thread MetadataContext metadataContext = MetadataContextHolder.get(); Map customMetadata = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); + Map disposableMetadata = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_DISPOSABLE); - if (!CollectionUtils.isEmpty(customMetadata)) { - String encodedTransitiveMetadata = JacksonUtils.serialize2Json(customMetadata); - requestTemplate.removeHeader(CUSTOM_METADATA); + // Clean up one-time metadata coming from upstream . + Map newestCustomMetadata = new HashMap<>(); + customMetadata.forEach((key, value) -> { + if (!disposableMetadata.containsKey(key)) { + newestCustomMetadata.put(key, value); + } + }); + this.buildMetadataHeader(requestTemplate, disposableMetadata, CUSTOM_DISPOSABLE_METADATA); + + // process custom metadata finally + this.buildMetadataHeader(requestTemplate, newestCustomMetadata, CUSTOM_METADATA); + } + + /** + * Set metadata into the request header for {@link RestTemplate} . + * @param requestTemplate instance of {@link RestTemplate} + * @param metadata metadata map . + * @param headerName target metadata http header name . + */ + private void buildMetadataHeader(RequestTemplate requestTemplate, Map metadata, String headerName) { + if (!CollectionUtils.isEmpty(metadata)) { + String encodedMetadata = JacksonUtils.serialize2Json(metadata); + requestTemplate.removeHeader(headerName); try { - requestTemplate.header(CUSTOM_METADATA, URLEncoder.encode(encodedTransitiveMetadata, UTF_8)); + requestTemplate.header(headerName, encode(encodedMetadata, UTF_8)); } catch (UnsupportedEncodingException e) { LOG.error("Set header failed.", e); - requestTemplate.header(CUSTOM_METADATA, encodedTransitiveMetadata); + requestTemplate.header(headerName, encodedMetadata); } } } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptor.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptor.java index 75f198193..513310da4 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptor.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateInterceptor.java @@ -21,6 +21,7 @@ package com.tencent.cloud.metadata.core; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; +import java.util.HashMap; import java.util.Map; import com.tencent.cloud.common.constant.MetadataConstant; @@ -33,9 +34,12 @@ import org.springframework.http.HttpRequest; import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpResponse; +import org.springframework.lang.NonNull; import org.springframework.util.CollectionUtils; import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; +import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUSTOM_DISPOSABLE_METADATA; +import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUSTOM_METADATA; /** * Interceptor used for adding the metadata in http headers from context when web client @@ -51,22 +55,44 @@ public class EncodeTransferMedataRestTemplateInterceptor implements ClientHttpRe } @Override - public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, - ClientHttpRequestExecution clientHttpRequestExecution) throws IOException { + public ClientHttpResponse intercept(@NonNull HttpRequest httpRequest, @NonNull byte[] bytes, + @NonNull ClientHttpRequestExecution clientHttpRequestExecution) throws IOException { // get metadata of current thread MetadataContext metadataContext = MetadataContextHolder.get(); Map customMetadata = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); + Map disposableMetadata = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_DISPOSABLE); - if (!CollectionUtils.isEmpty(customMetadata)) { - String encodedTransitiveMetadata = JacksonUtils.serialize2Json(customMetadata); + Map newestCustomMetadata = new HashMap<>(); + customMetadata.forEach((key, value) -> { + if (!disposableMetadata.containsKey(key)) { + newestCustomMetadata.put(key, value); + } + }); + // build custom disposable metadata request header + this.buildMetadataHeader(httpRequest, disposableMetadata, CUSTOM_DISPOSABLE_METADATA); + + // build custom metadata request header + this.buildMetadataHeader(httpRequest, newestCustomMetadata, CUSTOM_METADATA); + + return clientHttpRequestExecution.execute(httpRequest, bytes); + } + + /** + * Set metadata into the request header for {@link HttpRequest} . + * + * @param request instance of {@link HttpRequest} + * @param metadata metadata map . + * @param headerName target metadata http header name . + */ + private void buildMetadataHeader(HttpRequest request, Map metadata, String headerName) { + if (!CollectionUtils.isEmpty(metadata)) { + String encodedMetadata = JacksonUtils.serialize2Json(metadata); try { - httpRequest.getHeaders().set(MetadataConstant.HeaderName.CUSTOM_METADATA, - URLEncoder.encode(encodedTransitiveMetadata, UTF_8)); + request.getHeaders().set(headerName, URLEncoder.encode(encodedMetadata, UTF_8)); } catch (UnsupportedEncodingException e) { - httpRequest.getHeaders().set(MetadataConstant.HeaderName.CUSTOM_METADATA, encodedTransitiveMetadata); + request.getHeaders().set(headerName, encodedMetadata); } } - return clientHttpRequestExecution.execute(httpRequest, bytes); } } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilter.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilter.java index 4f6c00103..95d7b5b2c 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilter.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilter.java @@ -20,6 +20,7 @@ package com.tencent.cloud.metadata.core; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; +import java.util.HashMap; import java.util.Map; import com.tencent.cloud.common.constant.MetadataConstant; @@ -36,6 +37,8 @@ import org.springframework.util.CollectionUtils; import org.springframework.web.server.ServerWebExchange; import static com.tencent.cloud.common.constant.ContextConstant.UTF_8; +import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUSTOM_DISPOSABLE_METADATA; +import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUSTOM_METADATA; import static org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter.LOAD_BALANCER_CLIENT_FILTER_ORDER; /** @@ -59,22 +62,42 @@ public class EncodeTransferMedataScgFilter implements GlobalFilter, Ordered { // get metadata of current thread MetadataContext metadataContext = exchange.getAttribute(MetadataConstant.HeaderName.METADATA_CONTEXT); - - // add new metadata and cover old if (metadataContext == null) { metadataContext = MetadataContextHolder.get(); } + Map customMetadata = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); - if (!CollectionUtils.isEmpty(customMetadata)) { - String metadataStr = JacksonUtils.serialize2Json(customMetadata); + Map disposableMetadata = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_DISPOSABLE); + + // Clean upstream disposable metadata. + Map newestCustomMetadata = new HashMap<>(); + customMetadata.forEach((key, value) -> { + if (!disposableMetadata.containsKey(key)) { + newestCustomMetadata.put(key, value); + } + }); + + this.buildMetadataHeader(builder, newestCustomMetadata, CUSTOM_METADATA); + this.buildMetadataHeader(builder, disposableMetadata, CUSTOM_DISPOSABLE_METADATA); + + return chain.filter(exchange.mutate().request(builder.build()).build()); + } + + /** + * Set metadata into the request header for {@link ServerHttpRequest.Builder} . + * @param builder instance of {@link ServerHttpRequest.Builder} + * @param metadata metadata map . + * @param headerName target metadata http header name . + */ + private void buildMetadataHeader(ServerHttpRequest.Builder builder, Map metadata, String headerName) { + if (!CollectionUtils.isEmpty(metadata)) { + String encodedMetadata = JacksonUtils.serialize2Json(metadata); try { - builder.header(MetadataConstant.HeaderName.CUSTOM_METADATA, URLEncoder.encode(metadataStr, UTF_8)); + builder.header(headerName, URLEncoder.encode(encodedMetadata, UTF_8)); } catch (UnsupportedEncodingException e) { - builder.header(MetadataConstant.HeaderName.CUSTOM_METADATA, metadataStr); + builder.header(headerName, encodedMetadata); } } - - return chain.filter(exchange.mutate().request(builder.build()).build()); } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java index 5c52f2dfe..dad1725a8 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/PolarisServiceDiscovery.java @@ -18,6 +18,7 @@ package com.tencent.cloud.polaris.discovery; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -29,6 +30,7 @@ import com.tencent.polaris.api.pojo.ServiceInstances; import com.tencent.polaris.api.rpc.InstancesResponse; import org.springframework.cloud.client.ServiceInstance; +import org.springframework.util.CollectionUtils; /** * @author Haotian Zhang, Andrew Shan, Jie Cheng @@ -63,7 +65,10 @@ public class PolarisServiceDiscovery { * @throws PolarisException polarisException */ public List getServices() throws PolarisException { - return polarisDiscoveryHandler.GetServices().getServices().stream().map(ServiceInfo::getService) - .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(polarisDiscoveryHandler.GetServices().getServices())) { + return Collections.emptyList(); + } + return polarisDiscoveryHandler.GetServices().getServices().stream() + .map(ServiceInfo::getService).collect(Collectors.toList()); } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java index 1737bd469..a79eaf148 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java @@ -30,7 +30,6 @@ import com.tencent.polaris.client.api.SDKContext; import org.apache.commons.lang.StringUtils; import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; @@ -40,7 +39,7 @@ import org.springframework.util.CollectionUtils; * * @author Haotian Zhang, Andrew Shan, Jie Cheng */ -public class PolarisRegistration implements Registration, ServiceInstance { +public class PolarisRegistration implements Registration { private static final String METADATA_KEY_IP = "internal-ip"; private static final String METADATA_KEY_ADDRESS = "internal-address"; diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 7743b5f6c..93372d6dc 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -24,6 +24,12 @@ "defaultValue": true, "description": "enable polaris registration or not." }, + { + "name": "spring.cloud.polaris.discovery.heartbeat-interval", + "type": "java.lang.Integer", + "defaultValue": "5000", + "description": "Millis interval of Heart beat. Default: 5000." + }, { "name": "spring.cloud.polaris.discovery.health-check-url", "type": "java.lang.String", diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java index 09e17e1e8..5e451f3de 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/constant/MetadataConstant.java @@ -26,6 +26,12 @@ import org.springframework.core.Ordered; */ public final class MetadataConstant { + /** + * Default Private Constructor. + */ + private MetadataConstant() { + } + /** * Order of filter, interceptor, ... */ @@ -57,6 +63,11 @@ public final class MetadataConstant { */ public static final String CUSTOM_METADATA = "SCT-CUSTOM-METADATA"; + /** + * Custom Disposable Metadata. + */ + public static final String CUSTOM_DISPOSABLE_METADATA = "SCT-CUSTOM-DISPOSABLE-METADATA"; + /** * System Metadata. */ diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContext.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContext.java index bd18111a9..caa9ceef4 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContext.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContext.java @@ -40,6 +40,17 @@ public class MetadataContext { * transitive context. */ public static final String FRAGMENT_TRANSITIVE = "transitive"; + + /** + * disposable Context. + */ + public static final String FRAGMENT_DISPOSABLE = "disposable"; + + /** + * upstream disposable Context. + */ + public static final String FRAGMENT_UPSTREAM_DISPOSABLE = "upstream-disposable"; + private static final Logger LOG = LoggerFactory.getLogger(MetadataContext.class); /** * Namespace of local instance. diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java index 3d3064ba0..28520517b 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/MetadataContextHolder.java @@ -20,12 +20,17 @@ package com.tencent.cloud.common.metadata; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import org.springframework.util.CollectionUtils; +import static com.tencent.cloud.common.metadata.MetadataContext.FRAGMENT_DISPOSABLE; +import static com.tencent.cloud.common.metadata.MetadataContext.FRAGMENT_TRANSITIVE; +import static com.tencent.cloud.common.metadata.MetadataContext.FRAGMENT_UPSTREAM_DISPOSABLE; + /** * Metadata Context Holder. * @@ -36,6 +41,7 @@ public final class MetadataContextHolder { private static final ThreadLocal METADATA_CONTEXT = new InheritableThreadLocal<>(); private static MetadataLocalProperties metadataLocalProperties; + private static StaticMetadataManager staticMetadataManager; private MetadataContextHolder() { @@ -51,24 +57,55 @@ public final class MetadataContextHolder { } if (metadataLocalProperties == null) { - metadataLocalProperties = (MetadataLocalProperties) ApplicationContextAwareUtils - .getApplicationContext().getBean("metadataLocalProperties"); + metadataLocalProperties = ApplicationContextAwareUtils.getApplicationContext().getBean(MetadataLocalProperties.class); } if (staticMetadataManager == null) { - staticMetadataManager = (StaticMetadataManager) ApplicationContextAwareUtils - .getApplicationContext().getBean("metadataManager"); + staticMetadataManager = ApplicationContextAwareUtils.getApplicationContext().getBean(StaticMetadataManager.class); } // init static transitive metadata MetadataContext metadataContext = new MetadataContext(); - metadataContext.putFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE, - staticMetadataManager.getMergedStaticTransitiveMetadata()); + metadataContext.putFragmentContext(FRAGMENT_TRANSITIVE, staticMetadataManager.getMergedStaticTransitiveMetadata()); + metadataContext.putFragmentContext(FRAGMENT_DISPOSABLE, staticMetadataManager.getMergedStaticDisposableMetadata()); METADATA_CONTEXT.set(metadataContext); return METADATA_CONTEXT.get(); } + /** + * Get disposable metadata value from thread local . + * @param key metadata key . + * @param upstream upstream disposable , otherwise will return local static disposable metadata . + * @return target disposable metadata value . + */ + public static Optional getDisposableMetadata(String key, boolean upstream) { + MetadataContext context = get(); + if (upstream) { + return Optional.ofNullable(context.getContext(FRAGMENT_UPSTREAM_DISPOSABLE, key)); + } + else { + return Optional.ofNullable(context.getContext(FRAGMENT_DISPOSABLE, key)); + } + } + + /** + * Get all disposable metadata value from thread local . + * @param upstream upstream disposable , otherwise will return local static disposable metadata . + * @return target disposable metadata value . + */ + public static Map getAllDisposableMetadata(boolean upstream) { + Map disposables = new HashMap<>(); + MetadataContext context = get(); + if (upstream) { + disposables.putAll(context.getFragmentContext(FRAGMENT_UPSTREAM_DISPOSABLE)); + } + else { + disposables.putAll(context.getFragmentContext(FRAGMENT_DISPOSABLE)); + } + return Collections.unmodifiableMap(disposables); + } + /** * Set metadata context. * @param metadataContext metadata context @@ -80,21 +117,26 @@ public final class MetadataContextHolder { /** * Save metadata map to thread local. * @param dynamicTransitiveMetadata custom metadata collection + * @param dynamicDisposableMetadata custom disposable metadata connection */ - public static void init(Map dynamicTransitiveMetadata) { + public static void init(Map dynamicTransitiveMetadata, Map dynamicDisposableMetadata) { // Init ThreadLocal. MetadataContextHolder.remove(); MetadataContext metadataContext = MetadataContextHolder.get(); // Save transitive metadata to ThreadLocal. if (!CollectionUtils.isEmpty(dynamicTransitiveMetadata)) { - Map staticTransitiveMetadata = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); + Map staticTransitiveMetadata = metadataContext.getFragmentContext(FRAGMENT_TRANSITIVE); Map mergedTransitiveMetadata = new HashMap<>(); mergedTransitiveMetadata.putAll(staticTransitiveMetadata); mergedTransitiveMetadata.putAll(dynamicTransitiveMetadata); + metadataContext.putFragmentContext(FRAGMENT_TRANSITIVE, Collections.unmodifiableMap(mergedTransitiveMetadata)); + + Map mergedDisposableMetadata = new HashMap<>(dynamicDisposableMetadata); + metadataContext.putFragmentContext(FRAGMENT_UPSTREAM_DISPOSABLE, Collections.unmodifiableMap(mergedDisposableMetadata)); - metadataContext.putFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE, - Collections.unmodifiableMap(mergedTransitiveMetadata)); + Map staticDisposableMetadata = metadataContext.getFragmentContext(FRAGMENT_DISPOSABLE); + metadataContext.putFragmentContext(FRAGMENT_DISPOSABLE, Collections.unmodifiableMap(staticDisposableMetadata)); } MetadataContextHolder.set(metadataContext); } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java index a717db436..554694fa3 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java @@ -54,18 +54,22 @@ public class StaticMetadataManager { private static final String ENV_METADATA_PREFIX = "SCT_METADATA_CONTENT_"; private static final int ENV_METADATA_PREFIX_LENGTH = ENV_METADATA_PREFIX.length(); private static final String ENV_METADATA_CONTENT_TRANSITIVE = "SCT_METADATA_CONTENT_TRANSITIVE"; + private static final String ENV_METADATA_CONTENT_DISPOSABLE = "SCT_METADATA_CONTENT_DISPOSABLE"; private static final String ENV_METADATA_ZONE = "SCT_METADATA_ZONE"; private static final String ENV_METADATA_REGION = "SCT_METADATA_REGION"; private static final String ENV_METADATA_CAMPUS = "SCT_METADATA_CAMPUS"; private Map envMetadata; private Map envTransitiveMetadata; + private Map envDisposableMetadata; private Map configMetadata; private Map configTransitiveMetadata; + private Map configDisposableMetadata; private Map customSPIMetadata; private Map customSPITransitiveMetadata; - + private Map customSPIDisposableMetadata; private Map mergedStaticMetadata; private Map mergedStaticTransitiveMetadata; + private Map mergedStaticDisposableMetadata; private String zone; private String region; private String campus; @@ -85,6 +89,7 @@ public class StaticMetadataManager { LOGGER.info("[SCT] Loaded static metadata info. {}", this); } + @SuppressWarnings("DuplicatedCode") private void parseEnvMetadata() { Map allEnvs = System.getenv(); @@ -118,27 +123,54 @@ public class StaticMetadataManager { } } envTransitiveMetadata = Collections.unmodifiableMap(envTransitiveMetadata); + + envDisposableMetadata = new HashMap<>(); + // parse disposable metadata + String disposableKeys = allEnvs.get(ENV_METADATA_CONTENT_DISPOSABLE); + if (StringUtils.isNotBlank(disposableKeys)) { + String[] keyArr = StringUtils.split(disposableKeys, ","); + if (keyArr != null && keyArr.length > 0) { + for (String key : keyArr) { + String value = envMetadata.get(key); + if (StringUtils.isNotBlank(value)) { + envDisposableMetadata.put(key, value); + } + } + } + } + envDisposableMetadata = Collections.unmodifiableMap(envDisposableMetadata); } private void parseConfigMetadata(MetadataLocalProperties metadataLocalProperties) { Map allMetadata = metadataLocalProperties.getContent(); List transitiveKeys = metadataLocalProperties.getTransitive(); + List disposableKeys = metadataLocalProperties.getDisposable(); - Map result = new HashMap<>(); + Map transitiveResult = new HashMap<>(); for (String key : transitiveKeys) { if (allMetadata.containsKey(key)) { - result.put(key, allMetadata.get(key)); + transitiveResult.put(key, allMetadata.get(key)); } } - configTransitiveMetadata = Collections.unmodifiableMap(result); + Map disposableResult = new HashMap<>(); + for (String key : disposableKeys) { + if (allMetadata.containsKey(key)) { + disposableResult.put(key, allMetadata.get(key)); + } + } + + configTransitiveMetadata = Collections.unmodifiableMap(transitiveResult); + configDisposableMetadata = Collections.unmodifiableMap(disposableResult); configMetadata = Collections.unmodifiableMap(allMetadata); } + @SuppressWarnings("DuplicatedCode") private void parseCustomMetadata(InstanceMetadataProvider instanceMetadataProvider) { if (instanceMetadataProvider == null) { customSPIMetadata = Collections.emptyMap(); customSPITransitiveMetadata = Collections.emptyMap(); + customSPIDisposableMetadata = Collections.emptyMap(); return; } @@ -162,6 +194,17 @@ public class StaticMetadataManager { } } customSPITransitiveMetadata = Collections.unmodifiableMap(transitiveMetadata); + + Set disposableKeys = instanceMetadataProvider.getDisposableMetadataKeys(); + Map disposableMetadata = new HashMap<>(); + if (!CollectionUtils.isEmpty(disposableKeys)) { + for (String key : disposableKeys) { + if (customSPIMetadata.containsKey(key)) { + disposableMetadata.put(key, customSPIMetadata.get(key)); + } + } + } + customSPIDisposableMetadata = Collections.unmodifiableMap(disposableMetadata); } private void merge() { @@ -173,15 +216,19 @@ public class StaticMetadataManager { mergedMetadataResult.putAll(customSPIMetadata); // set location info as metadata mergedMetadataResult.putAll(getLocationMetadata()); - this.mergedStaticMetadata = Collections.unmodifiableMap(mergedMetadataResult); Map mergedTransitiveMetadataResult = new HashMap<>(); mergedTransitiveMetadataResult.putAll(configTransitiveMetadata); mergedTransitiveMetadataResult.putAll(envTransitiveMetadata); mergedTransitiveMetadataResult.putAll(customSPITransitiveMetadata); - this.mergedStaticTransitiveMetadata = Collections.unmodifiableMap(mergedTransitiveMetadataResult); + + Map mergedDisposableMetadataResult = new HashMap<>(); + mergedDisposableMetadataResult.putAll(configDisposableMetadata); + mergedDisposableMetadataResult.putAll(envDisposableMetadata); + mergedDisposableMetadataResult.putAll(customSPIDisposableMetadata); + this.mergedStaticDisposableMetadata = Collections.unmodifiableMap(mergedDisposableMetadataResult); } private void parseLocationMetadata(MetadataLocalProperties metadataLocalProperties, @@ -228,6 +275,10 @@ public class StaticMetadataManager { return envTransitiveMetadata; } + public Map getEnvDisposableMetadata() { + return envDisposableMetadata; + } + public Map getAllConfigMetadata() { return configMetadata; } @@ -236,6 +287,10 @@ public class StaticMetadataManager { return configTransitiveMetadata; } + public Map getConfigDisposableMetadata() { + return configDisposableMetadata; + } + public Map getAllCustomMetadata() { return customSPIMetadata; } @@ -244,6 +299,10 @@ public class StaticMetadataManager { return customSPITransitiveMetadata; } + public Map getCustomSPIDisposableMetadata() { + return customSPIDisposableMetadata; + } + public Map getMergedStaticMetadata() { return mergedStaticMetadata; } @@ -252,6 +311,10 @@ public class StaticMetadataManager { return mergedStaticTransitiveMetadata; } + public Map getMergedStaticDisposableMetadata() { + return mergedStaticDisposableMetadata; + } + public String getZone() { return zone; } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataLocalProperties.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataLocalProperties.java index 0d0039bc3..2964e0178 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataLocalProperties.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/config/MetadataLocalProperties.java @@ -43,6 +43,11 @@ public class MetadataLocalProperties { */ private List transitive; + /** + * A disposable metadata key list . + */ + private List disposable; + public Map getContent() { if (CollectionUtils.isEmpty(content)) { content = new HashMap<>(); @@ -64,4 +69,15 @@ public class MetadataLocalProperties { public void setTransitive(List transitive) { this.transitive = transitive; } + + public List getDisposable() { + if (CollectionUtils.isEmpty(disposable)) { + disposable = new ArrayList<>(); + } + return disposable; + } + + public void setDisposable(List disposable) { + this.disposable = disposable; + } } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpoint.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpoint.java index 360018ea2..ea7954c37 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpoint.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/endpoint/PolarisMetadataEndpoint.java @@ -45,9 +45,14 @@ public class PolarisMetadataEndpoint { result.put("Env", staticMetadataManager.getAllEnvMetadata()); result.put("EnvTransitive", staticMetadataManager.getEnvTransitiveMetadata()); result.put("ConfigTransitive", staticMetadataManager.getConfigTransitiveMetadata()); + result.put("ConfigDisposable", staticMetadataManager.getConfigDisposableMetadata()); result.put("Config", staticMetadataManager.getAllConfigMetadata()); result.put("MergeStatic", staticMetadataManager.getMergedStaticMetadata()); - result.put("CustomSPI", staticMetadataManager.getCustomSPITransitiveMetadata()); + result.put("MergeStaticTransitive", staticMetadataManager.getMergedStaticTransitiveMetadata()); + result.put("MergeStaticDisposable", staticMetadataManager.getMergedStaticDisposableMetadata()); + result.put("CustomSPI", staticMetadataManager.getAllCustomMetadata()); + result.put("CustomSPITransitive", staticMetadataManager.getCustomSPITransitiveMetadata()); + result.put("CustomSPIDisposable", staticMetadataManager.getCustomSPIDisposableMetadata()); result.put("zone", staticMetadataManager.getZone()); result.put("region", staticMetadataManager.getRegion()); result.put("campus", staticMetadataManager.getCampus()); diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/InstanceMetadataProvider.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/InstanceMetadataProvider.java index 5434aa140..44cfaf605 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/InstanceMetadataProvider.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/spi/InstanceMetadataProvider.java @@ -43,6 +43,13 @@ public interface InstanceMetadataProvider { return Collections.emptySet(); } + /** + * @return the keys of disposable metadata. + */ + default Set getDisposableMetadataKeys() { + return Collections.emptySet(); + } + /** * The region of current instance. * diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java index 609026dc4..521866c34 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/JacksonUtils.java @@ -22,6 +22,7 @@ import java.util.Map; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,8 +52,25 @@ public final class JacksonUtils { * @return Json String */ public static String serialize2Json(T object) { + return serialize2Json(object, false); + } + + /** + * Object to Json. + * @param object object to be serialized + * @param pretty pretty print + * @param type of object + * @return Json String + */ + public static String serialize2Json(T object, boolean pretty) { try { - return OM.writeValueAsString(object); + if (pretty) { + ObjectWriter objectWriter = OM.writerWithDefaultPrettyPrinter(); + return objectWriter.writeValueAsString(object); + } + else { + return OM.writeValueAsString(object); + } } catch (JsonProcessingException e) { LOG.error("Object to Json failed. {}", object, e); diff --git a/spring-cloud-tencent-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-tencent-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 390f49158..575ca9738 100644 --- a/spring-cloud-tencent-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-tencent-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -9,6 +9,11 @@ "name": "spring.cloud.tencent.metadata.transitive", "type": "java.util.List", "description": "Custom transitive metadata key list." + }, + { + "name": "spring.cloud.tencent.metadata.disposable", + "type": "java.util.List", + "description": "Custom disposable metadata key list." } ] } diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/MetadataContextHolderTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/MetadataContextHolderTest.java index 811b3c2d5..c6b7cbcd2 100644 --- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/MetadataContextHolderTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/MetadataContextHolderTest.java @@ -58,7 +58,7 @@ public class MetadataContextHolderTest { customMetadata.put("a", "1"); customMetadata.put("b", "22"); customMetadata.put("c", "3"); - MetadataContextHolder.init(customMetadata); + MetadataContextHolder.init(customMetadata, new HashMap<>()); metadataContext = MetadataContextHolder.get(); customMetadata = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); Assertions.assertThat(customMetadata.get("a")).isEqualTo("1"); diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index 056e12155..76fc8f233 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -73,7 +73,7 @@ 1.7.0-2021.0.3-SNAPSHOT - 1.7.1 + 1.7.2 31.0.1-jre 1.2.11 4.5.1 diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/README-zh.md b/spring-cloud-tencent-examples/metadata-transfer-example/README-zh.md index 9af9aff6d..764a80c38 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/README-zh.md +++ b/spring-cloud-tencent-examples/metadata-transfer-example/README-zh.md @@ -4,7 +4,7 @@ 本样例将介绍如何在Spring Cloud项目中使用```spring-cloud-starter-tencent-metadata-transfer```以使用其各项功能。 -本样例包括```metadata-callee-service```、```metadata-caller-service```。 +本样例包括```metadata-frontend```、```metadata-middle```、```metadata-backend```。 ## 使用说明 @@ -41,8 +41,9 @@ spring: ##### IDEA启动 分别启动 -- ```spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service```的```MetadataCalleeService``` -- ```spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service```的```MetadataCallerService``` +- ```spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend```的```MetadataFrontendService``` +- ```spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle```的```MetadataMiddleService``` +- ```spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend```的```MetadataBackendService``` ##### Maven打包启动 @@ -53,7 +54,7 @@ spring: mvn clean package ``` -然后在```metadata-callee-service```、```metadata-caller-service```下找到生成的jar包,运行 +然后在```metadata-frontend```、```metadata-middle```、```metadata-backend```下找到生成的jar包,运行 ``` java -jar ${app.jar} @@ -63,7 +64,7 @@ java -jar ${app.jar} ### 元数据配置 -在```spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service```项目的```bootstrap.yml```配置文件中 +- 在```spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend```项目的```bootstrap.yml```配置文件中 ```yaml spring: @@ -76,10 +77,37 @@ spring: CUSTOM-METADATA-KEY-LOCAL: CUSTOM-VALUE-LOCAL # 示例:可传递元数据 CUSTOM-METADATA-KEY-TRANSITIVE: CUSTOM-VALUE-TRANSITIVE + # 示例:一次性元数据 + CUSTOM-METADATA-KEY-DISPOSABLE: CUSTOM-VALUE-DISPOSABLE-FRONTEND # 指定哪个元数据的键值将沿着链接传递 transitive: - CUSTOM-METADATA-KEY-TRANSITIVE + # 指定哪个元数据的键值只进行一次性传递(一跳) + disposable: + - CUSTOM-METADATA-KEY-DISPOSABLE +``` + +- 在```spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend```项目的```bootstrap.yml```配置文件中 +```yaml +spring: + cloud: + tencent: + metadata: + # 定义元数据的键值对 + content: + # 示例:本地元数据,默认不在链路中传递 + CUSTOM-METADATA-KEY-LOCAL-2: CUSTOM-VALUE-LOCAL-2 + # 示例:可传递元数据 + CUSTOM-METADATA-KEY-TRANSITIVE-2: CUSTOM-VALUE-TRANSITIVE-2 + # 示例:一次性元数据 + CUSTOM-METADATA-KEY-DISPOSABLE: CUSTOM-VALUE-DISPOSABLE-MIDDLE + # 指定哪个元数据的键值将沿着链接传递 + transitive: + - CUSTOM-METADATA-KEY-TRANSITIVE-2 + # 指定哪个元数据的键值只进行一次性传递(一跳) + disposable: + - CUSTOM-METADATA-KEY-DISPOSABLE ``` ### 验证 @@ -87,31 +115,85 @@ spring: #### 请求调用 ```shell -curl -L -X GET 'http://127.0.0.1:48080/metadata/service/caller/feign/info' +curl -L -X GET 'http://127.0.0.1:48080/metadata/service/frontend/feign/info' ``` 预期返回值 -``` +```json { - "caller-metadata-contents": { + "frontend-transitive-metadata": { + "CUSTOM-METADATA-KEY-TRANSITIVE": "CUSTOM-VALUE-TRANSITIVE" + }, + "frontend-upstream-disposable-metadata": { + }, + "frontend-local-disposable-metadata": { + "CUSTOM-METADATA-KEY-DISPOSABLE": "CUSTOM-VALUE-DISPOSABLE-FRONTEND" + }, + + "middle-transitive-metadata": { "CUSTOM-METADATA-KEY-TRANSITIVE": "CUSTOM-VALUE-TRANSITIVE", - "CUSTOM-METADATA-KEY-LOCAL": "CUSTOM-VALUE-LOCAL" + "CUSTOM-METADATA-KEY-TRANSITIVE-2": "CUSTOM-VALUE-TRANSITIVE-2" }, - "callee-transitive-metadata": { - "CUSTOM-METADATA-KEY-TRANSITIVE": "CUSTOM-VALUE-TRANSITIVE" + "middle-upstream-disposable-metadata": { + "CUSTOM-METADATA-KEY-DISPOSABLE": "CUSTOM-VALUE-DISPOSABLE-FRONTEND" }, - "caller-transitive-metadata": { - "CUSTOM-METADATA-KEY-TRANSITIVE": "CUSTOM-VALUE-TRANSITIVE" + "middle-local-disposable-metadata": { + "CUSTOM-METADATA-KEY-DISPOSABLE": "CUSTOM-VALUE-DISPOSABLE-MIDDLE" + }, + + "backend-transitive-metadata": { + "CUSTOM-METADATA-KEY-TRANSITIVE": "CUSTOM-VALUE-TRANSITIVE", + "CUSTOM-METADATA-KEY-TRANSITIVE-2": "CUSTOM-VALUE-TRANSITIVE-2" + }, + "backend-upstream-disposable-metadata": { + "CUSTOM-METADATA-KEY-DISPOSABLE": "CUSTOM-VALUE-DISPOSABLE-MIDDLE" + }, + "backend-local-disposable-metadata": { } } ``` 返回值解析 -- Key `caller-metadata-contents` 表示 `metadata-caller-service` 项目中默认配置的所有的元数据。 -- Key `caller-transitive-metadata` 表示 `metadata-caller-service` 项目中指定的可以在链路中传递的元数据列表。 -- Key `callee-transitive-metadata` 表示 `metadata-callee-service` 项目被 `metadata-caller-service` 调用时传递过来的上游的元数据列表。 +> `*`(星号),代表示例中的`frontend`、`middle`、`backend`。 + +- Key `*-transitive-metadata` 表示服务中默认配置的所有的可传递(全链路)的元数据。 +- Key `*-upstream-disposable-metadata` 表示服务中从上游请求中获取到的一次性传递的元数据。 +- Key `*-local-disposable-metadata` 表示当前服务配置的往下游传递的一次性的元数据。 + +### 如何通过Api获取传递的元数据 + +- 获取全局传递的元数据 + +```java +MetadataContext context = MetadataContextHolder.get(); + Map customMetadataMap = context.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); + +customMetadataMap.forEach((key, value) -> { + // ... +}); + +``` + +- 获取上游传递过来的一次性元数据 + +```java +Map upstreamDisposableMetadatas = MetadataContextHolder.getAllDisposableMetadata(true); +upstreamDisposableMetadatas.forEach((key, value) -> { + // ... +}); +``` + +- 获取本地配置的一次性元数据 + +```java +Map localDisposableMetadatas = MetadataContextHolder.getAllDisposableMetadata(false); +localDisposableMetadatas.forEach((key, value) -> { + // ... +}); +``` + ### Wiki参考 diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/README.md b/spring-cloud-tencent-examples/metadata-transfer-example/README.md index b0d912ce9..9fc663666 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/README.md +++ b/spring-cloud-tencent-examples/metadata-transfer-example/README.md @@ -2,9 +2,10 @@ ## Example Introduction -This example shows how to use ```spring-cloud-starter-tencent-metadata-transfer``` in Spring Cloud project for its features. +This example shows how to use ```spring-cloud-starter-tencent-metadata-transfer``` in Spring Cloud project for its +features. -This example contains ```metadata-callee-service```、```metadata-caller-service```. +This example contains ```metadata-frontend```、```metadata-middle```、```metadata-backend```. ## Instruction @@ -40,8 +41,10 @@ Reference to [Polaris Getting Started](https://github.com/PolarisMesh/polaris#ge - IDEA Launching -- ```spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service```‘s```MetadataCalleeService``` -- ```spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service```'s```MetadataCallerService``` +- ```spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend```'s ```MetadataFrontendService``` +- ```spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle```'s ```MetadataMiddleService``` +- ```spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend```'s ```MetadataBackendService``` + - Maven Package Launching @@ -51,7 +54,7 @@ Execute under ```spring-cloud-tencent-examples/metadata-transfer-example``` mvn clean package ``` -Then find the jars under ```metadata-callee-service```、```metadata-caller-service```, and run it: +Then find the jars under ```metadata-frontend```、```metadata-middle```、```metadata-backend```, and run it: ``` java -jar ${app.jar} @@ -62,7 +65,7 @@ Launch application, change ${app.jar} to jar's package name. ### Metadata Configuration -In the ```bootstrap.yml``` configuration file of the ```spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service``` project +- In the ```bootstrap.yml``` configuration file of the ```spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend``` project ```yaml spring: @@ -75,9 +78,38 @@ spring: CUSTOM-METADATA-KEY-LOCAL: CUSTOM-VALUE-LOCAL # Example: transitive CUSTOM-METADATA-KEY-TRANSITIVE: CUSTOM-VALUE-TRANSITIVE + # Example: disposable + CUSTOM-METADATA-KEY-DISPOSABLE: CUSTOM-VALUE-DISPOSABLE-FRONTEND # Assigned which metadata key-value will be passed along the link transitive: - CUSTOM-METADATA-KEY-TRANSITIVE + # Specify which metadata key value will be passed only once (one-step) + disposable: + - CUSTOM-METADATA-KEY-DISPOSABLE + +``` + +- In the ```bootstrap.yml``` configuration file of the ```spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle``` project + +```yaml +spring: + cloud: + tencent: + metadata: + # Defined your metadata keys & values + content: + # Example: intransitive + CUSTOM-METADATA-KEY-LOCAL-2: CUSTOM-VALUE-LOCAL-2 + # Example: transitive + CUSTOM-METADATA-KEY-TRANSITIVE-2: CUSTOM-VALUE-TRANSITIVE-2 + # Example: disposable + CUSTOM-METADATA-KEY-DISPOSABLE: CUSTOM-VALUE-DISPOSABLE-MIDDLE + # Assigned which metadata key-value will be passed along the link + transitive: + - CUSTOM-METADATA-KEY-TRANSITIVE-2 + # Specify which metadata key value will be passed only once (one-step) + disposable: + - CUSTOM-METADATA-KEY-DISPOSABLE ``` @@ -93,24 +125,77 @@ Expected return rate ``` { - "caller-metadata-contents": { + "frontend-transitive-metadata": { + "CUSTOM-METADATA-KEY-TRANSITIVE": "CUSTOM-VALUE-TRANSITIVE" + }, + "frontend-upstream-disposable-metadata": { + }, + "frontend-local-disposable-metadata": { + "CUSTOM-METADATA-KEY-DISPOSABLE": "CUSTOM-VALUE-DISPOSABLE-FRONTEND" + }, + + "middle-transitive-metadata": { "CUSTOM-METADATA-KEY-TRANSITIVE": "CUSTOM-VALUE-TRANSITIVE", - "CUSTOM-METADATA-KEY-LOCAL": "CUSTOM-VALUE-LOCAL" + "CUSTOM-METADATA-KEY-TRANSITIVE-2": "CUSTOM-VALUE-TRANSITIVE-2" }, - "callee-transitive-metadata": { - "CUSTOM-METADATA-KEY-TRANSITIVE": "CUSTOM-VALUE-TRANSITIVE" + "middle-upstream-disposable-metadata": { + "CUSTOM-METADATA-KEY-DISPOSABLE": "CUSTOM-VALUE-DISPOSABLE-FRONTEND" }, - "caller-transitive-metadata": { - "CUSTOM-METADATA-KEY-TRANSITIVE": "CUSTOM-VALUE-TRANSITIVE" + "middle-local-disposable-metadata": { + "CUSTOM-METADATA-KEY-DISPOSABLE": "CUSTOM-VALUE-DISPOSABLE-MIDDLE" + }, + + "backend-transitive-metadata": { + "CUSTOM-METADATA-KEY-TRANSITIVE": "CUSTOM-VALUE-TRANSITIVE", + "CUSTOM-METADATA-KEY-TRANSITIVE-2": "CUSTOM-VALUE-TRANSITIVE-2" + }, + "backend-upstream-disposable-metadata": { + "CUSTOM-METADATA-KEY-DISPOSABLE": "CUSTOM-VALUE-DISPOSABLE-MIDDLE" + }, + "backend-local-disposable-metadata": { } } ``` Response value description -- Key `caller-metadata-contents` represents all metadata configured by default in the `metadata-caller-service` project. -- Key `caller-transitive-metadata` represents the list of metadata that can be passed in the link specified in the `metadata-caller-service` item. -- Key `callee-transitive-metadata` represents the list of upstream metadata passed when the `metadata-callee-service` project is called by `metadata-caller-service`. +> `*` (asterisk), representing `frontend`, `middle`, `backend` in the example. + +- Key `*-transitive-metadata` represents all the passable (fully linked) metadata configured by default in the service. +- Key `*-upstream-disposable-metadata` indicates the one-time transmissible metadata obtained from upstream requests in the service. +- Key `*-local-disposable-metadata` indicates the one-time metadata passed downstream as configured by the current service. + +### How to get the passed metadata via Api + +- Get the metadata passed globally + +```java +MetadataContext context = MetadataContextHolder.get(); + Map customMetadataMap = context.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); + +customMetadataMap.forEach((key, value) -> { + // ... +}); +``` + +- Get disposable(one-time) metadata passed from upstream + +```java +Map upstreamDisposableMetadatas = MetadataContextHolder.getAllDisposableMetadata(true); +upstreamDisposableMetadatas.forEach((key, value) -> { + // ... +}); +``` + +- Get disposable(one-time) metadata for local configuration + +```java +Map localDisposableMetadatas = MetadataContextHolder.getAllDisposableMetadata(false); +localDisposableMetadatas.forEach((key, value) -> { + // ... +}); +``` + ### Wiki Reference diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service/pom.xml b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/pom.xml similarity index 93% rename from spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service/pom.xml rename to spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/pom.xml index 237c9877f..106c2ed78 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service/pom.xml +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/pom.xml @@ -10,8 +10,8 @@ 4.0.0 - metadata-callee-service - Spring Cloud Tencent Metadata Transfer Callee Service + metadata-backend + Spring Cloud Tencent Metadata Transfer Backend Service diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service/src/main/java/com/tencent/cloud/metadata/service/callee/MetadataCalleeController.java b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/src/main/java/com/tencent/cloud/metadata/service/backend/MetadataBackendController.java similarity index 57% rename from spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service/src/main/java/com/tencent/cloud/metadata/service/callee/MetadataCalleeController.java rename to spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/src/main/java/com/tencent/cloud/metadata/service/backend/MetadataBackendController.java index 4966e9bdc..7da621e81 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service/src/main/java/com/tencent/cloud/metadata/service/callee/MetadataCalleeController.java +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/src/main/java/com/tencent/cloud/metadata/service/backend/MetadataBackendController.java @@ -15,8 +15,9 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.metadata.service.callee; +package com.tencent.cloud.metadata.service.backend; +import java.util.HashMap; import java.util.Map; import com.tencent.cloud.common.metadata.MetadataContext; @@ -35,10 +36,10 @@ import org.springframework.web.bind.annotation.RestController; * @author Palmer Xu */ @RestController -@RequestMapping("/metadata/service/callee") -public class MetadataCalleeController { +@RequestMapping("/metadata/service/backend") +public class MetadataBackendController { - private static final Logger LOG = LoggerFactory.getLogger(MetadataCalleeController.class); + private static final Logger LOG = LoggerFactory.getLogger(MetadataBackendController.class); @Value("${server.port:0}") private int port; @@ -48,18 +49,36 @@ public class MetadataCalleeController { * @return information of callee */ @GetMapping("/info") - public Map info() { - LOG.info("Metadata Service Callee [{}] is called.", port); + public Map> info() { + LOG.info("Metadata Backend Service [{}] is called.", port); + Map> ret = new HashMap<>(); // Get Custom Metadata From Context MetadataContext context = MetadataContextHolder.get(); Map customMetadataMap = context.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); customMetadataMap.forEach((key, value) -> { - LOG.info("Custom Metadata (Key-Value): {} : {}", key, value); + LOG.info("Metadata Backend Custom Metadata (Key-Value): {} : {}", key, value); }); - return customMetadataMap; - } + ret.put("backend-transitive-metadata", customMetadataMap); + + // Get All Disposable metadata from upstream service + Map upstreamDisposableMetadatas = MetadataContextHolder.getAllDisposableMetadata(true); + upstreamDisposableMetadatas.forEach((key, value) -> { + LOG.info("Upstream Disposable Metadata (Key-Value): {} : {}", key, value); + }); + + ret.put("backend-upstream-disposable-metadata", upstreamDisposableMetadatas); + // Get All Disposable metadata from upstream service + Map localDisposableMetadatas = MetadataContextHolder.getAllDisposableMetadata(false); + localDisposableMetadatas.forEach((key, value) -> { + LOG.info("Local Custom Disposable Metadata (Key-Value): {} : {}", key, value); + }); + + ret.put("backend-local-disposable-metadata", localDisposableMetadatas); + + return ret; + } } diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service/src/main/java/com/tencent/cloud/metadata/service/callee/MetadataCalleeService.java b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/src/main/java/com/tencent/cloud/metadata/service/backend/MetadataBackendService.java similarity index 86% rename from spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service/src/main/java/com/tencent/cloud/metadata/service/callee/MetadataCalleeService.java rename to spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/src/main/java/com/tencent/cloud/metadata/service/backend/MetadataBackendService.java index 06771a5e8..964cb8274 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service/src/main/java/com/tencent/cloud/metadata/service/callee/MetadataCalleeService.java +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/src/main/java/com/tencent/cloud/metadata/service/backend/MetadataBackendService.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.metadata.service.callee; +package com.tencent.cloud.metadata.service.backend; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -26,10 +26,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; * @author Palmer Xu */ @SpringBootApplication -public class MetadataCalleeService { +public class MetadataBackendService { public static void main(String[] args) { - SpringApplication.run(MetadataCalleeService.class, args); + SpringApplication.run(MetadataBackendService.class, args); } - } diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/src/main/resources/bootstrap.yml similarity index 58% rename from spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service/src/main/resources/bootstrap.yml rename to spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/src/main/resources/bootstrap.yml index 85c842c7c..4188f3cc3 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-callee-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-backend/src/main/resources/bootstrap.yml @@ -1,8 +1,8 @@ server: - port: 48084 + port: 48088 spring: application: - name: MetadataCalleeService + name: MetadataBackendService cloud: polaris: address: grpc://183.47.111.80:8091 @@ -11,3 +11,10 @@ spring: discovery: enabled: true register: true + +management: + endpoints: + web: + exposure: + include: + - polaris-metadata \ No newline at end of file diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCallerController.java b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCallerController.java deleted file mode 100644 index cf9ec84eb..000000000 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCallerController.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.metadata.service.caller; - -import java.util.Map; - -import com.google.common.collect.Maps; -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.common.metadata.MetadataContextHolder; -import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.RestTemplate; - -/** - * Metadata caller controller. - * - * @author Palmer Xu - */ -@RestController -@RequestMapping("/metadata/service/caller") -public class MetadataCallerController { - - private final RestTemplate restTemplate; - - private final MetadataCalleeService metadataCalleeService; - - private final MetadataLocalProperties metadataLocalProperties; - - public MetadataCallerController(RestTemplate restTemplate, - MetadataCalleeService metadataCalleeService, - MetadataLocalProperties metadataLocalProperties) { - this.restTemplate = restTemplate; - this.metadataCalleeService = metadataCalleeService; - this.metadataLocalProperties = metadataLocalProperties; - } - - /** - * Get metadata info from remote service. - * @return metadata map - */ - @GetMapping("/feign/info") - public Map> feign() { - Map> ret = Maps.newHashMap(); - - // Call remote service with feign client - Map calleeMetadata = metadataCalleeService.info(); - ret.put("callee-transitive-metadata", calleeMetadata); - - // Get Custom Metadata From Context - MetadataContext context = MetadataContextHolder.get(); - Map callerTransitiveMetadata = context.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); - ret.put("caller-transitive-metadata", callerTransitiveMetadata); - ret.put("caller-metadata-contents", metadataLocalProperties.getContent()); - - return ret; - } - - /** - * Get metadata information of callee. - * @return information of callee - */ - @SuppressWarnings("unchecked") - @GetMapping("/rest/info") - public Map> rest() { - Map> ret = Maps.newHashMap(); - - // Call remote service with RestTemplate - Map calleeMetadata = restTemplate.getForObject( - "http://MetadataCalleeService/metadata/service/callee/info", - Map.class); - ret.put("callee-transitive-metadata", calleeMetadata); - - // Get Custom Metadata From Context - MetadataContext context = MetadataContextHolder.get(); - Map callerTransitiveMetadata = context.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); - ret.put("caller-transitive-metadata", callerTransitiveMetadata); - ret.put("caller-metadata-contents", metadataLocalProperties.getContent()); - - return ret; - } - - /** - * health check. - * @return health check info - */ - @GetMapping("/healthCheck") - public String healthCheck() { - return "pk ok"; - } - -} diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/pom.xml b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/pom.xml new file mode 100644 index 000000000..4b6adb14e --- /dev/null +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/pom.xml @@ -0,0 +1,51 @@ + + + + metadata-transfer-example + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + + metadata-frontend + Spring Cloud Tencent Metadata Transfer Frontent Service + + + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-discovery + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.0 + + + attach-sources + + jar + + + + + + + diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/java/com/tencent/cloud/metadata/service/frontend/MetadataFrontendController.java b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/java/com/tencent/cloud/metadata/service/frontend/MetadataFrontendController.java new file mode 100644 index 000000000..3d107f555 --- /dev/null +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/java/com/tencent/cloud/metadata/service/frontend/MetadataFrontendController.java @@ -0,0 +1,155 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.service.frontend; + +import java.util.HashMap; +import java.util.Map; + +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.metadata.MetadataContextHolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +/** + * Metadata caller controller. + * + * @author Palmer Xu + */ +@RestController +@RequestMapping("/metadata/service/frontend") +public class MetadataFrontendController { + + private static final Logger LOG = LoggerFactory.getLogger(MetadataFrontendController.class); + + private final RestTemplate restTemplate; + + private final MetadataMiddleService metadataMiddleService; + + public MetadataFrontendController(RestTemplate restTemplate, + MetadataMiddleService metadataMiddleService) { + this.restTemplate = restTemplate; + this.metadataMiddleService = metadataMiddleService; + } + + /** + * Get metadata info from remote service. + * + * @return metadata map + */ + @GetMapping("/feign/info") + public Map> feign() { + Map> ret = new HashMap<>(); + + // Call remote service with feign client + Map> middleResult = metadataMiddleService.info(); + + if (middleResult != null) { + ret.putAll(middleResult); + } + + // Get Custom Metadata From Context + MetadataContext context = MetadataContextHolder.get(); + Map customMetadataMap = context.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); + + customMetadataMap.forEach((key, value) -> { + LOG.info("Metadata Middle Custom Metadata (Key-Value): {} : {}", key, value); + }); + + ret.put("frontend-transitive-metadata", customMetadataMap); + + // Get All Disposable metadata from upstream service + Map upstreamDisposableMetadatas = MetadataContextHolder.getAllDisposableMetadata(true); + upstreamDisposableMetadatas.forEach((key, value) -> { + LOG.info("Upstream Custom Disposable Metadata (Key-Value): {} : {}", key, value); + }); + + ret.put("frontend-upstream-disposable-metadata", upstreamDisposableMetadatas); + + // Get All Disposable metadata from upstream service + Map localDisposableMetadatas = MetadataContextHolder.getAllDisposableMetadata(false); + localDisposableMetadatas.forEach((key, value) -> { + LOG.info("Local Custom Disposable Metadata (Key-Value): {} : {}", key, value); + }); + + ret.put("frontend-local-disposable-metadata", localDisposableMetadatas); + + return ret; + } + + /** + * Get metadata information of callee. + * + * @return information of callee + */ + @SuppressWarnings("unchecked") + @GetMapping("/rest/info") + public Map> rest() { + Map> ret = new HashMap<>(); + + // Call remote service with RestTemplate + Map> middleResult = restTemplate.getForObject( + "http://MetadataMiddleService/metadata/service/middle/info", Map.class); + + if (middleResult != null) { + ret.putAll(middleResult); + } + + // Get Custom Metadata From Context + MetadataContext context = MetadataContextHolder.get(); + Map customMetadataMap = context.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); + + customMetadataMap.forEach((key, value) -> { + LOG.info("Metadata Middle Custom Metadata (Key-Value): {} : {}", key, value); + }); + + ret.put("frontend-transitive-metadata", customMetadataMap); + + // Get All Disposable metadata from upstream service + Map upstreamDisposableMetadatas = MetadataContextHolder.getAllDisposableMetadata(true); + upstreamDisposableMetadatas.forEach((key, value) -> { + LOG.info("Upstream Custom Disposable Metadata (Key-Value): {} : {}", key, value); + }); + + ret.put("frontend-upstream-disposable-metadata", upstreamDisposableMetadatas); + + // Get All Disposable metadata from upstream service + Map localDisposableMetadatas = MetadataContextHolder.getAllDisposableMetadata(false); + localDisposableMetadatas.forEach((key, value) -> { + LOG.info("Local Custom Disposable Metadata (Key-Value): {} : {}", key, value); + }); + + ret.put("frontend-local-disposable-metadata", localDisposableMetadatas); + + return ret; + } + + /** + * health check. + * + * @return health check info + */ + @GetMapping("/healthCheck") + public String healthCheck() { + return "pk ok"; + } +} diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCallerService.java b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/java/com/tencent/cloud/metadata/service/frontend/MetadataFrontendService.java similarity index 84% rename from spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCallerService.java rename to spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/java/com/tencent/cloud/metadata/service/frontend/MetadataFrontendService.java index a586c7e72..cdea235d3 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCallerService.java +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/java/com/tencent/cloud/metadata/service/frontend/MetadataFrontendService.java @@ -15,11 +15,10 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.metadata.service.caller; +package com.tencent.cloud.metadata.service.frontend; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; @@ -31,12 +30,11 @@ import org.springframework.web.client.RestTemplate; * @author Palmer Xu */ @SpringBootApplication -@EnableDiscoveryClient @EnableFeignClients -public class MetadataCallerService { +public class MetadataFrontendService { public static void main(String[] args) { - SpringApplication.run(MetadataCallerService.class, args); + SpringApplication.run(MetadataFrontendService.class, args); } @Bean @@ -44,5 +42,4 @@ public class MetadataCallerService { public RestTemplate restTemplate() { return new RestTemplate(); } - } diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCalleeService.java b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/java/com/tencent/cloud/metadata/service/frontend/MetadataMiddleService.java similarity index 78% rename from spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCalleeService.java rename to spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/java/com/tencent/cloud/metadata/service/frontend/MetadataMiddleService.java index 65bea6707..ea0bde432 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCalleeService.java +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/java/com/tencent/cloud/metadata/service/frontend/MetadataMiddleService.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.metadata.service.caller; +package com.tencent.cloud.metadata.service.frontend; import java.util.Map; @@ -27,15 +27,14 @@ import org.springframework.web.bind.annotation.GetMapping; * * @author Palmer Xu */ -@FeignClient(value = "MetadataCalleeService", - fallback = MetadataCalleeServiceFallback.class) -public interface MetadataCalleeService { +@FeignClient(value = "MetadataMiddleService", + fallback = MetadataMiddleServiceFallback.class) +public interface MetadataMiddleService { /** * Get information of callee. * @return information of callee */ - @GetMapping("/metadata/service/callee/info") - Map info(); - + @GetMapping("/metadata/service/middle/info") + Map> info(); } diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCalleeServiceFallback.java b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/java/com/tencent/cloud/metadata/service/frontend/MetadataMiddleServiceFallback.java similarity index 84% rename from spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCalleeServiceFallback.java rename to spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/java/com/tencent/cloud/metadata/service/frontend/MetadataMiddleServiceFallback.java index ba508831a..727f65c63 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/java/com/tencent/cloud/metadata/service/caller/MetadataCalleeServiceFallback.java +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/java/com/tencent/cloud/metadata/service/frontend/MetadataMiddleServiceFallback.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.metadata.service.caller; +package com.tencent.cloud.metadata.service.frontend; import java.util.Map; @@ -29,11 +29,10 @@ import org.springframework.stereotype.Component; * @author Palmer Xu */ @Component -public class MetadataCalleeServiceFallback implements MetadataCalleeService { +public class MetadataMiddleServiceFallback implements MetadataMiddleService { @Override - public Map info() { + public Map> info() { return Maps.newHashMap(); } - } diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/resources/bootstrap.yml similarity index 71% rename from spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/resources/bootstrap.yml rename to spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/resources/bootstrap.yml index a390f51a6..719424131 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-frontend/src/main/resources/bootstrap.yml @@ -2,7 +2,7 @@ server: port: 48080 spring: application: - name: MetadataCallerService + name: MetadataFrontendService cloud: polaris: address: grpc://183.47.111.80:8091 @@ -12,18 +12,22 @@ spring: enabled: true register: true heartbeat-enabled: true - health-check-url: /metadata/service/caller/healthCheck + health-check-url: /metadata/service/frontend/healthCheck tencent: metadata: # Defined your metadata keys & values content: # Example: intransitive CUSTOM-METADATA-KEY-LOCAL: CUSTOM-VALUE-LOCAL + # Example: disposable + CUSTOM-METADATA-KEY-DISPOSABLE: CUSTOM-VALUE-DISPOSABLE # Example: transitive - CUSTOM-METADATA-KEY-TRANSITIVE: CUSTOM-VALUE-TRANSITIVE + CUSTOM-METADATA-KEY-TRANSITIVE: CUSTOM-VALUE-TRANSITIVE-FRONTEND # Assigned which metadata key-value will be passed along the link transitive: - CUSTOM-METADATA-KEY-TRANSITIVE + disposable: + - CUSTOM-METADATA-KEY-DISPOSABLE management: endpoints: web: diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/pom.xml b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/pom.xml similarity index 93% rename from spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/pom.xml rename to spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/pom.xml index 1c1306805..41c4cd13f 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-caller-service/pom.xml +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/pom.xml @@ -10,8 +10,8 @@ 4.0.0 - metadata-caller-service - Spring Cloud Tencent Metadata Transfer Caller Service + metadata-middle + Spring Cloud Tencent Metadata Transfer Middle Service diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/java/com/tencent/cloud/metadata/service/middle/MetadataBackendService.java b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/java/com/tencent/cloud/metadata/service/middle/MetadataBackendService.java new file mode 100644 index 000000000..b8e9855c9 --- /dev/null +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/java/com/tencent/cloud/metadata/service/middle/MetadataBackendService.java @@ -0,0 +1,40 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.service.middle; + +import java.util.Map; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; + +/** + * Metadata callee feign client. + * + * @author Palmer Xu + */ +@FeignClient(value = "MetadataBackendService", + fallback = MetadataBackendServiceFallback.class) +public interface MetadataBackendService { + + /** + * Get information of callee. + * @return information of callee + */ + @GetMapping("/metadata/service/backend/info") + Map> info(); +} diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/java/com/tencent/cloud/metadata/service/middle/MetadataBackendServiceFallback.java b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/java/com/tencent/cloud/metadata/service/middle/MetadataBackendServiceFallback.java new file mode 100644 index 000000000..cbe5edd71 --- /dev/null +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/java/com/tencent/cloud/metadata/service/middle/MetadataBackendServiceFallback.java @@ -0,0 +1,38 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.service.middle; + +import java.util.Map; + +import com.google.common.collect.Maps; + +import org.springframework.stereotype.Component; + +/** + * Metadata callee feign client fallback. + * + * @author Palmer Xu + */ +@Component +public class MetadataBackendServiceFallback implements MetadataBackendService { + + @Override + public Map> info() { + return Maps.newHashMap(); + } +} diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/java/com/tencent/cloud/metadata/service/middle/MetadataMiddleController.java b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/java/com/tencent/cloud/metadata/service/middle/MetadataMiddleController.java new file mode 100644 index 000000000..7ea673a50 --- /dev/null +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/java/com/tencent/cloud/metadata/service/middle/MetadataMiddleController.java @@ -0,0 +1,122 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.service.middle; + +import java.util.HashMap; +import java.util.Map; + +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.metadata.MetadataContextHolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +import static com.tencent.cloud.common.util.JacksonUtils.serialize2Json; + +/** + * Metadata callee controller. + * + * @author Palmer Xu + */ +@RestController +@RequestMapping("/metadata/service/middle") +public class MetadataMiddleController { + + private static final Logger LOG = LoggerFactory.getLogger(MetadataMiddleController.class); + + @Value("${server.port:0}") + private int port; + + private final MetadataBackendService metadataBackendService; + + private final RestTemplate restTemplate; + + public MetadataMiddleController(MetadataBackendService metadataBackendService, RestTemplate restTemplate) { + this.metadataBackendService = metadataBackendService; + this.restTemplate = restTemplate; + } + + /** + * Get information of callee. + * + * @return information of callee + */ + @GetMapping("/info") + public Map> info() { + + // Build result + Map> ret = new HashMap<>(); + + LOG.info("Metadata Middle Service [{}] is called.", port); + + // Call remote service with RestTemplate + Map> backendResult = restTemplate.getForObject( + "http://MetadataBackendService/metadata/service/backend/info", Map.class); + + if (backendResult != null) { + LOG.info("RestTemplate Backend Metadata"); + LOG.info("\r{}", serialize2Json(backendResult, true)); + backendResult.clear(); + } + + // Call remote service with Feign + backendResult = metadataBackendService.info(); + if (backendResult != null) { + LOG.info("Feign Backend Metadata"); + LOG.info("\r{}", serialize2Json(backendResult, true)); + } + + if (backendResult != null) { + ret.putAll(backendResult); + } + + // Get Custom Metadata From Context + MetadataContext context = MetadataContextHolder.get(); + Map customMetadataMap = context.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); + + customMetadataMap.forEach((key, value) -> { + LOG.info("Metadata Middle Custom Metadata (Key-Value): {} : {}", key, value); + }); + + ret.put("middle-transitive-metadata", customMetadataMap); + + // Get All Disposable metadata from upstream service + Map upstreamDisposableMetadatas = MetadataContextHolder.getAllDisposableMetadata(true); + upstreamDisposableMetadatas.forEach((key, value) -> { + LOG.info("Upstream Custom Disposable Metadata (Key-Value): {} : {}", key, value); + }); + + ret.put("middle-upstream-disposable-metadata", upstreamDisposableMetadatas); + + // Get All Disposable metadata from upstream service + Map localDisposableMetadatas = MetadataContextHolder.getAllDisposableMetadata(false); + localDisposableMetadatas.forEach((key, value) -> { + LOG.info("Local Custom Disposable Metadata (Key-Value): {} : {}", key, value); + }); + + ret.put("middle-local-disposable-metadata", localDisposableMetadatas); + + return ret; + } + +} diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/java/com/tencent/cloud/metadata/service/middle/MetadataMiddleService.java b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/java/com/tencent/cloud/metadata/service/middle/MetadataMiddleService.java new file mode 100644 index 000000000..f7c8d3d08 --- /dev/null +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/java/com/tencent/cloud/metadata/service/middle/MetadataMiddleService.java @@ -0,0 +1,46 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.metadata.service.middle; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.Bean; +import org.springframework.web.client.RestTemplate; + +/** + * Metadata callee application. + * + * @author Palmer Xu + */ +@SpringBootApplication +@EnableFeignClients +public class MetadataMiddleService { + + public static void main(String[] args) { + SpringApplication.run(MetadataMiddleService.class, args); + } + + @Bean + @LoadBalanced + public RestTemplate restTemplate() { + return new RestTemplate(); + } + +} diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..db78677b5 --- /dev/null +++ b/spring-cloud-tencent-examples/metadata-transfer-example/metadata-middle/src/main/resources/bootstrap.yml @@ -0,0 +1,35 @@ +server: + port: 48084 +spring: + application: + name: MetadataMiddleService + cloud: + polaris: + address: grpc://183.47.111.80:8091 + namespace: default + enabled: true + discovery: + enabled: true + register: true + tencent: + metadata: + # Defined your metadata keys & values + content: + # Example: intransitive + CUSTOM-METADATA-KEY-LOCAL-2: CUSTOM-VALUE-LOCAL-2 + # Example: transitive + CUSTOM-METADATA-KEY-TRANSITIVE-2: CUSTOM-VALUE-TRANSITIVE-2 + # Example: disposable + CUSTOM-METADATA-KEY-DISPOSABLE: CUSTOM-VALUE-DISPOSABLE-MIDDLE + # Assigned which metadata key-value will be passed along the link + transitive: + - CUSTOM-METADATA-KEY-TRANSITIVE-2 + disposable: + - CUSTOM-METADATA-KEY-DISPOSABLE + +management: + endpoints: + web: + exposure: + include: + - polaris-metadata \ No newline at end of file diff --git a/spring-cloud-tencent-examples/metadata-transfer-example/pom.xml b/spring-cloud-tencent-examples/metadata-transfer-example/pom.xml index bd2b961ec..2cbc55a3b 100644 --- a/spring-cloud-tencent-examples/metadata-transfer-example/pom.xml +++ b/spring-cloud-tencent-examples/metadata-transfer-example/pom.xml @@ -15,8 +15,9 @@ Spring Cloud Starter Tencent Metadata Transfer Example - metadata-callee-service - metadata-caller-service + metadata-frontend + metadata-middle + metadata-backend diff --git a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml index a3b008536..de8c607b2 100644 --- a/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-circuitbreaker-example/polaris-circuitbreaker-example-a/src/main/resources/bootstrap.yml @@ -15,12 +15,14 @@ spring: port: 28081 loadbalancer: configurations: polaris -# tencent: -# rpc-enhancement: -# enabled: true -# ignore-internal-server-error: true -# series: server_error -# statuses: gateway_timeout, bad_gateway, service_unavailable + tencent: + rpc-enhancement: + enabled: true + reporter: + ignore-internal-server-error: true + series: server_error + statuses: gateway_timeout, bad_gateway, service_unavailable + feign: circuitbreaker: enabled: true diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerTest.java new file mode 100644 index 000000000..d80888a74 --- /dev/null +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerTest.java @@ -0,0 +1,128 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.loadbalancer; + +import java.util.ArrayList; +import java.util.List; + +import com.tencent.cloud.common.pojo.PolarisServiceInstance; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.cloud.polaris.loadbalancer.config.PolarisLoadBalancerProperties; +import com.tencent.polaris.api.pojo.Instance; +import com.tencent.polaris.router.api.core.RouterAPI; +import com.tencent.polaris.router.api.rpc.ProcessLoadBalanceResponse; +import org.assertj.core.api.Assertions; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.loadbalancer.Request; +import org.springframework.cloud.client.loadbalancer.Response; +import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; + +import static com.tencent.cloud.common.metadata.MetadataContext.LOCAL_NAMESPACE; +import static com.tencent.cloud.common.metadata.MetadataContext.LOCAL_SERVICE; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + + +/** + * Test for {@link PolarisLoadBalancer}. + * + * @author rod.xu + */ +@RunWith(MockitoJUnitRunner.class) +public class PolarisLoadBalancerTest { + + @Mock + private RouterAPI routerAPI; + @Mock + private ObjectProvider supplierObjectProvider; + @Mock + private PolarisLoadBalancerProperties loadBalancerProperties; + + private static MockedStatic mockedApplicationContextAwareUtils; + private static Instance testInstance; + + @BeforeClass + public static void beforeClass() { + mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn("unit-test"); + + testInstance = Instance.createDefaultInstance("instance-id", LOCAL_NAMESPACE, + LOCAL_SERVICE, "host", 8090); + } + + @AfterClass + public static void afterClass() { + mockedApplicationContextAwareUtils.close(); + } + + @Test + public void chooseNormalLogicTest_thenReturnAvailablePolarisInstance() { + + Request request = Mockito.mock(Request.class); + List mockInstanceList = new ArrayList<>(); + mockInstanceList.add(new PolarisServiceInstance(testInstance)); + + ServiceInstanceListSupplier serviceInstanceListSupplier = Mockito.mock(ServiceInstanceListSupplier.class); + when(serviceInstanceListSupplier.get(request)).thenReturn(Flux.just(mockInstanceList)); + + when(supplierObjectProvider.getIfAvailable(any())).thenReturn(serviceInstanceListSupplier); + when(loadBalancerProperties.getEnabled()).thenReturn(true); + + ProcessLoadBalanceResponse mockLbRes = new ProcessLoadBalanceResponse(testInstance); + when(routerAPI.processLoadBalance(any())).thenReturn(mockLbRes); + + // request construct and execute invoke + PolarisLoadBalancer polarisLoadBalancer = new PolarisLoadBalancer(LOCAL_SERVICE, supplierObjectProvider, + loadBalancerProperties, routerAPI); + Mono> responseMono = polarisLoadBalancer.choose(request); + ServiceInstance serviceInstance = responseMono.block().getServer(); + + // verify method has invoked + verify(loadBalancerProperties).getEnabled(); + verify(supplierObjectProvider).getIfAvailable(any()); + + //result assert + Assertions.assertThat(serviceInstance).isNotNull(); + Assertions.assertThat(serviceInstance instanceof PolarisServiceInstance).isTrue(); + + PolarisServiceInstance polarisServiceInstance = (PolarisServiceInstance) serviceInstance; + + Assertions.assertThat(polarisServiceInstance.getPolarisInstance().getId()).isEqualTo("instance-id"); + Assertions.assertThat(polarisServiceInstance.getPolarisInstance().getNamespace()).isEqualTo(LOCAL_NAMESPACE); + Assertions.assertThat(polarisServiceInstance.getPolarisInstance().getService()).isEqualTo(LOCAL_SERVICE); + Assertions.assertThat(polarisServiceInstance.getPolarisInstance().getHost()).isEqualTo("host"); + Assertions.assertThat(polarisServiceInstance.getPolarisInstance().getPort()).isEqualTo(8090); + } + +} diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisServiceInstanceListSupplierTest.java b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisServiceInstanceListSupplierTest.java new file mode 100644 index 000000000..22062b0cf --- /dev/null +++ b/spring-cloud-tencent-polaris-loadbalancer/src/test/java/com/tencent/cloud/polaris/loadbalancer/PolarisServiceInstanceListSupplierTest.java @@ -0,0 +1,94 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.loadbalancer; + +import java.util.ArrayList; +import java.util.List; + +import com.tencent.cloud.common.pojo.PolarisServiceInstance; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import org.assertj.core.api.Assertions; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; + +import static com.tencent.cloud.common.metadata.MetadataContext.LOCAL_NAMESPACE; +import static org.mockito.ArgumentMatchers.anyString; + +/** + * Test for {@link PolarisServiceInstanceListSupplier}. + * + * @author rod.xu + */ +@RunWith(MockitoJUnitRunner.class) +public class PolarisServiceInstanceListSupplierTest { + + @Mock + private ServiceInstanceListSupplier serviceInstanceListSupplier; + + @Test + public void chooseInstancesTest() { + try (MockedStatic mockedApplicationContextAwareUtils = Mockito + .mockStatic(ApplicationContextAwareUtils.class)) { + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn("test-unit"); + + PolarisServiceInstanceListSupplier instanceListSupplier = + new PolarisServiceInstanceListSupplier(serviceInstanceListSupplier); + + List allServers = new ArrayList<>(); + ServiceInstance instance1 = new DefaultServiceInstance("unit-test-instanceId-01", + "unit-test-serviceId", "unit-test-host-01", 8090, false); + ServiceInstance instance2 = new DefaultServiceInstance("unit-test-instanceId-02", + "unit-test-serviceId", "unit-test-host-02", 8090, false); + + allServers.add(instance1); + allServers.add(instance2); + + List polarisInstanceList = instanceListSupplier.chooseInstances(allServers); + + Assertions.assertThat(polarisInstanceList).isNotNull(); + Assertions.assertThat(polarisInstanceList.size()).isEqualTo(allServers.size()); + + for (ServiceInstance serviceInstance : polarisInstanceList) { + Assertions.assertThat(serviceInstance instanceof PolarisServiceInstance).isTrue(); + + PolarisServiceInstance polarisServiceInstance = (PolarisServiceInstance) serviceInstance; + + Assertions.assertThat(polarisServiceInstance.isSecure()).isFalse(); + Assertions.assertThat(polarisServiceInstance.getPolarisInstance().getService()) + .isEqualTo("unit-test-serviceId"); + Assertions.assertThat(polarisServiceInstance.getPolarisInstance().getNamespace()) + .isEqualTo(LOCAL_NAMESPACE); + Assertions.assertThat(polarisServiceInstance.getPolarisInstance().getPort()).isEqualTo(8090); + Assertions.assertThat(polarisServiceInstance.getPolarisInstance().getId() + .startsWith("unit-test-instanceId")).isTrue(); + Assertions.assertThat(polarisServiceInstance.getPolarisInstance().getHost() + .startsWith("unit-test-host")).isTrue(); + } + } + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java index 41b9fe154..6ba28617d 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java @@ -22,7 +22,7 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementProperties; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,19 +50,17 @@ import static org.springframework.http.HttpStatus.VARIANT_ALSO_NEGOTIATES; public abstract class AbstractPolarisReporterAdapter { private static final Logger LOG = LoggerFactory.getLogger(AbstractPolarisReporterAdapter.class); - - protected final RpcEnhancementProperties properties; - private static final List HTTP_STATUSES = toList(NOT_IMPLEMENTED, BAD_GATEWAY, SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT, HTTP_VERSION_NOT_SUPPORTED, VARIANT_ALSO_NEGOTIATES, INSUFFICIENT_STORAGE, LOOP_DETECTED, BANDWIDTH_LIMIT_EXCEEDED, NOT_EXTENDED, NETWORK_AUTHENTICATION_REQUIRED); + protected final RpcEnhancementReporterProperties properties; /** - * Constructor With {@link RpcEnhancementProperties} . + * Constructor With {@link RpcEnhancementReporterProperties} . * - * @param properties instance of {@link RpcEnhancementProperties}. + * @param properties instance of {@link RpcEnhancementReporterProperties}. */ - protected AbstractPolarisReporterAdapter(RpcEnhancementProperties properties) { + protected AbstractPolarisReporterAdapter(RpcEnhancementReporterProperties properties) { this.properties = properties; } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java index 4dc25c30b..ab22b6b5c 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java @@ -50,7 +50,7 @@ import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE; */ @Configuration(proxyBeanMethods = false) @ConditionalOnProperty(value = "spring.cloud.tencent.rpc-enhancement.enabled", havingValue = "true", matchIfMissing = true) -@EnableConfigurationProperties(RpcEnhancementProperties.class) +@EnableConfigurationProperties(RpcEnhancementReporterProperties.class) @AutoConfigureAfter(PolarisContextAutoConfiguration.class) public class RpcEnhancementAutoConfiguration { @@ -76,7 +76,7 @@ public class RpcEnhancementAutoConfiguration { static class PolarisReporterConfig { @Bean - public SuccessPolarisReporter successPolarisReporter(RpcEnhancementProperties properties) { + public SuccessPolarisReporter successPolarisReporter(RpcEnhancementReporterProperties properties) { return new SuccessPolarisReporter(properties); } @@ -99,15 +99,15 @@ public class RpcEnhancementAutoConfiguration { @Bean public EnhancedRestTemplateReporter polarisRestTemplateResponseErrorHandler( - RpcEnhancementProperties properties, ConsumerAPI consumerAPI, + RpcEnhancementReporterProperties properties, ConsumerAPI consumerAPI, @Autowired(required = false) PolarisResponseErrorHandler polarisResponseErrorHandler) { return new EnhancedRestTemplateReporter(properties, consumerAPI, polarisResponseErrorHandler); } @Bean public EnhancedRestTemplateModifier polarisRestTemplateBeanPostProcessor( - EnhancedRestTemplateReporter enhancedRestTemplateReporter) { - return new EnhancedRestTemplateModifier(enhancedRestTemplateReporter); + EnhancedRestTemplateReporter restTemplateResponseErrorHandler) { + return new EnhancedRestTemplateModifier(restTemplateResponseErrorHandler); } } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementProperties.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterProperties.java similarity index 79% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementProperties.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterProperties.java index 612a97fbe..a044f459c 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementProperties.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterProperties.java @@ -29,27 +29,22 @@ import org.springframework.http.HttpStatus; * * @author Elve.Xu 2022-07-08 */ -@ConfigurationProperties("spring.cloud.tencent.rpc-enhancement") -public class RpcEnhancementProperties { +@ConfigurationProperties("spring.cloud.tencent.rpc-enhancement.reporter") +public class RpcEnhancementReporterProperties { /** - * If circuit-breaker enabled. - */ - private boolean enabled = true; - - /** - * Specify the Http status code(s) that needs to be fused. + * Specify the Http status code(s) that needs to be reported as FAILED. */ private List statuses = new ArrayList<>(); /** - * Specify List of HTTP status series. + * Specify List of HTTP status series that needs to be reported as FAILED when status list is empty. */ private List series = toList(HttpStatus.Series.SERVER_ERROR); /** - * Ignore Internal Server Error Http Status Code, - * Only takes effect if the attribute {@link RpcEnhancementProperties#series} is not empty. + * If ignore "Internal Server Error Http Status Code (500)", + * Only takes effect if the attribute {@link RpcEnhancementReporterProperties#series} is not empty. */ private boolean ignoreInternalServerError = true; @@ -81,14 +76,6 @@ public class RpcEnhancementProperties { this.series = series; } - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - public boolean isIgnoreInternalServerError() { return ignoreInternalServerError; } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java index e2bb22b32..d4dc77344 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java @@ -18,7 +18,7 @@ package com.tencent.cloud.rpc.enhancement.feign.plugin.reporter; import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementProperties; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin; import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; @@ -42,14 +42,13 @@ import org.springframework.http.HttpStatus; public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter implements EnhancedFeignPlugin { private static final Logger LOG = LoggerFactory.getLogger(SuccessPolarisReporter.class); + @Autowired(required = false) + private ConsumerAPI consumerAPI; - public SuccessPolarisReporter(RpcEnhancementProperties properties) { + public SuccessPolarisReporter(RpcEnhancementReporterProperties properties) { super(properties); } - @Autowired(required = false) - private ConsumerAPI consumerAPI; - @Override public String getName() { return SuccessPolarisReporter.class.getName(); diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java index 71fcea9ac..4051452b8 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporter.java @@ -26,7 +26,7 @@ import java.util.Objects; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.util.ReflectionUtils; import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementProperties; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.api.pojo.RetStatus; import com.tencent.polaris.api.pojo.ServiceKey; @@ -55,7 +55,7 @@ public class EnhancedRestTemplateReporter extends AbstractPolarisReporterAdapter private final PolarisResponseErrorHandler polarisResponseErrorHandler; - public EnhancedRestTemplateReporter(RpcEnhancementProperties properties, ConsumerAPI consumerAPI, + public EnhancedRestTemplateReporter(RpcEnhancementReporterProperties properties, ConsumerAPI consumerAPI, PolarisResponseErrorHandler polarisResponseErrorHandler) { super(properties); this.consumerAPI = consumerAPI; diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 77baec1e6..c76a18566 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-tencent-rpc-enhancement/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -1,5 +1,29 @@ { "properties": [ + { + "name": "spring.cloud.tencent.rpc-enhancement.enabled", + "type": "java.lang.Boolean", + "defaultValue": true, + "description": "If rpc enhancement enabled." + }, + { + "name": "spring.cloud.tencent.rpc-enhancement.reporter.ignore-internal-server-error", + "type": "java.lang.Boolean", + "defaultValue": true, + "description": "If ignore \"Internal Server Error Http Status Code (500)\"." + }, + { + "name": "spring.cloud.tencent.rpc-enhancement.reporter.series", + "type": "java.util.List", + "defaultValue": "HttpStatus.Series.SERVER_ERROR", + "description": "Specify List of HTTP status series that needs to be reported as FAILED when status list is empty." + }, + { + "name": "spring.cloud.tencent.rpc-enhancement.reporter.statuses", + "type": "java.util.List", + "defaultValue": "", + "description": "Specify the Http status code(s) that needs to be reported as FAILED." + }, { "name": "spring.cloud.polaris.stat.enabled", "type": "java.lang.Boolean", diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java index db205c313..a14655de3 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java @@ -17,7 +17,7 @@ package com.tencent.cloud.rpc.enhancement; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementProperties; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; import org.assertj.core.api.Assertions; import org.junit.Test; @@ -32,7 +32,7 @@ public class AbstractPolarisReporterAdapterTest { @Test public void testApplyWithDefaultConfig() { - RpcEnhancementProperties properties = new RpcEnhancementProperties(); + RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); // Mock Condition SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties); @@ -44,7 +44,7 @@ public class AbstractPolarisReporterAdapterTest { @Test public void testApplyWithoutIgnoreInternalServerError() { - RpcEnhancementProperties properties = new RpcEnhancementProperties(); + RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); // Mock Condition properties.getStatuses().clear(); properties.setIgnoreInternalServerError(false); @@ -59,7 +59,7 @@ public class AbstractPolarisReporterAdapterTest { @Test public void testApplyWithIgnoreInternalServerError() { - RpcEnhancementProperties properties = new RpcEnhancementProperties(); + RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); // Mock Condition properties.getStatuses().clear(); properties.setIgnoreInternalServerError(true); @@ -74,7 +74,7 @@ public class AbstractPolarisReporterAdapterTest { @Test public void testApplyWithoutSeries() { - RpcEnhancementProperties properties = new RpcEnhancementProperties(); + RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); // Mock Condition properties.getStatuses().clear(); properties.getSeries().clear(); @@ -89,7 +89,7 @@ public class AbstractPolarisReporterAdapterTest { @Test public void testApplyWithSeries() { - RpcEnhancementProperties properties = new RpcEnhancementProperties(); + RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); // Mock Condition properties.getStatuses().clear(); properties.getSeries().clear(); @@ -109,7 +109,7 @@ public class AbstractPolarisReporterAdapterTest { */ public static class SimplePolarisReporterAdapter extends AbstractPolarisReporterAdapter { - public SimplePolarisReporterAdapter(RpcEnhancementProperties properties) { + public SimplePolarisReporterAdapter(RpcEnhancementReporterProperties properties) { super(properties); } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterPropertiesTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterPropertiesTest.java new file mode 100644 index 000000000..48c61233b --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterPropertiesTest.java @@ -0,0 +1,64 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.rpc.enhancement.config; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.http.HttpStatus.MOVED_PERMANENTLY; +import static org.springframework.http.HttpStatus.MULTIPLE_CHOICES; +import static org.springframework.http.HttpStatus.Series.CLIENT_ERROR; +import static org.springframework.http.HttpStatus.Series.SERVER_ERROR; + +/** + * Test For {@link RpcEnhancementReporterProperties}. + * + * @author Haotian Zhang + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = RpcEnhancementReporterPropertiesTest.TestApplication.class) +@ActiveProfiles("test") +public class RpcEnhancementReporterPropertiesTest { + + @Autowired + private RpcEnhancementReporterProperties rpcEnhancementReporterProperties; + + @Test + public void testDefaultInitialization() { + assertThat(rpcEnhancementReporterProperties).isNotNull(); + assertThat(rpcEnhancementReporterProperties.isIgnoreInternalServerError()).isFalse(); + assertThat(rpcEnhancementReporterProperties.getSeries()).isNotEmpty(); + assertThat(rpcEnhancementReporterProperties.getSeries().get(0)).isEqualTo(CLIENT_ERROR); + assertThat(rpcEnhancementReporterProperties.getSeries().get(1)).isEqualTo(SERVER_ERROR); + assertThat(rpcEnhancementReporterProperties.getStatuses()).isNotEmpty(); + assertThat(rpcEnhancementReporterProperties.getStatuses().get(0)).isEqualTo(MULTIPLE_CHOICES); + assertThat(rpcEnhancementReporterProperties.getStatuses().get(1)).isEqualTo(MOVED_PERMANENTLY); + } + + @SpringBootApplication + protected static class TestApplication { + + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java index 631155b8f..7d54b6b8c 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java @@ -22,7 +22,7 @@ import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementProperties; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; import com.tencent.polaris.api.core.ConsumerAPI; import org.junit.Test; import org.junit.runner.RunWith; @@ -49,7 +49,7 @@ public class EnhancedRestTemplateReporterTest { public void handleError() throws Exception { ConsumerAPI consumerAPI = mock(ConsumerAPI.class); EnhancedRestTemplateReporter enhancedRestTemplateReporter = - new EnhancedRestTemplateReporter(mock(RpcEnhancementProperties.class), consumerAPI, null); + new EnhancedRestTemplateReporter(mock(RpcEnhancementReporterProperties.class), consumerAPI, null); URI uri = mock(URI.class); when(uri.getPath()).thenReturn("/test"); when(uri.getHost()).thenReturn("host"); diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/resources/application-test.properties b/spring-cloud-tencent-rpc-enhancement/src/test/resources/application-test.properties index 96d94d0d0..34e566e79 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/resources/application-test.properties +++ b/spring-cloud-tencent-rpc-enhancement/src/test/resources/application-test.properties @@ -1,3 +1,8 @@ spring.cloud.polaris.stat.enabled=true spring.cloud.polaris.stat.port=20000 spring.cloud.polaris.stat.path=/xxx +spring.cloud.tencent.rpc-enhancement.reporter.ignore-internal-server-error=false +spring.cloud.tencent.rpc-enhancement.reporter.series[0]=CLIENT_ERROR +spring.cloud.tencent.rpc-enhancement.reporter.series[1]=SERVER_ERROR +spring.cloud.tencent.rpc-enhancement.reporter.statuses[0]=MULTIPLE_CHOICES +spring.cloud.tencent.rpc-enhancement.reporter.statuses[1]=MOVED_PERMANENTLY