From 75f72ab0231cafee1c8b116225be6fadeee0ab53 Mon Sep 17 00:00:00 2001 From: shedfreewu <49236872+shedfreewu@users.noreply.github.com> Date: Thu, 20 Nov 2025 17:38:51 +0800 Subject: [PATCH] feat: support TagUtils, ContextToHeaderInterceptor in TSF(2024). (#1754) --- CHANGELOG.md | 3 +- .../MetadataTransferAutoConfiguration.java | 24 +++-- ...codeTransferMedataFeignEnhancedPlugin.java | 14 +++ ...nsferMedataRestTemplateEnhancedPlugin.java | 15 +++ ...EncodeTransferMedataScgEnhancedPlugin.java | 15 +++ ...TransferMedataWebClientEnhancedPlugin.java | 16 ++++ .../EncodeTransferMedataScgFilterTest.java | 3 +- .../filter/ContextToHeaderInterceptor.java | 30 ++++++ .../tsf/core/util/TagUtils.java | 64 +++++++++++++ .../tsf/core/util/TagUtilsTest.java | 92 +++++++++++++++++++ .../TestContextToHeaderInterceptor.java | 40 ++++++++ .../tsf/demo/provider/ProviderController.java | 15 +++ 12 files changed, 321 insertions(+), 10 deletions(-) create mode 100644 spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/filter/ContextToHeaderInterceptor.java create mode 100644 spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/util/TagUtils.java create mode 100644 spring-cloud-tencent-commons/src/test/java/org/springframework/tsf/core/util/TagUtilsTest.java create mode 100644 spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/TestContextToHeaderInterceptor.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 16eed687f..f720b3d46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,4 +5,5 @@ - [refactor:optimize auto configuration.](https://github.com/Tencent/spring-cloud-tencent/pull/1739) - [refactor:optimize config locate.](https://github.com/Tencent/spring-cloud-tencent/pull/1741) - [feat:support async metadata transfer.](https://github.com/Tencent/spring-cloud-tencent/pull/1743) -- [fix:replace with string inside @ConditionalOnClass.](https://github.com/Tencent/spring-cloud-tencent/pull/1750) \ No newline at end of file +- [fix:replace with string inside @ConditionalOnClass.](https://github.com/Tencent/spring-cloud-tencent/pull/1750) +- [feat: support TagUtils, ContextToHeaderInterceptor in TSF.](https://github.com/Tencent/spring-cloud-tencent/pull/1754) diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java index a7d4e6d94..394ffa886 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/config/MetadataTransferAutoConfiguration.java @@ -17,6 +17,8 @@ package com.tencent.cloud.metadata.config; +import java.util.List; + import com.tencent.cloud.common.async.PolarisAsyncProperties; import com.tencent.cloud.common.constant.OrderConstant; import com.tencent.cloud.metadata.core.DecodeTransferMetadataReactiveFilter; @@ -26,12 +28,14 @@ import com.tencent.cloud.metadata.core.EncodeTransferMedataRestTemplateEnhancedP import com.tencent.cloud.metadata.core.EncodeTransferMedataScgEnhancedPlugin; import com.tencent.cloud.metadata.core.EncodeTransferMedataWebClientEnhancedPlugin; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.tsf.core.filter.ContextToHeaderInterceptor; import static jakarta.servlet.DispatcherType.ASYNC; import static jakarta.servlet.DispatcherType.ERROR; @@ -92,8 +96,9 @@ public class MetadataTransferAutoConfiguration { protected static class MetadataTransferScgFilterConfig { @Bean - public EncodeTransferMedataScgEnhancedPlugin encodeTransferMedataScgEnhancedPlugin() { - return new EncodeTransferMedataScgEnhancedPlugin(); + public EncodeTransferMedataScgEnhancedPlugin encodeTransferMedataScgEnhancedPlugin( + @Autowired(required = false) List contextToHeaderInterceptorList) { + return new EncodeTransferMedataScgEnhancedPlugin(contextToHeaderInterceptorList); } } @@ -106,8 +111,9 @@ public class MetadataTransferAutoConfiguration { protected static class MetadataTransferFeignInterceptorConfig { @Bean - public EncodeTransferMedataFeignEnhancedPlugin encodeTransferMedataFeignEnhancedPlugin() { - return new EncodeTransferMedataFeignEnhancedPlugin(); + public EncodeTransferMedataFeignEnhancedPlugin encodeTransferMedataFeignEnhancedPlugin( + @Autowired(required = false) List contextToHeaderInterceptorList) { + return new EncodeTransferMedataFeignEnhancedPlugin(contextToHeaderInterceptorList); } } @@ -120,8 +126,9 @@ public class MetadataTransferAutoConfiguration { protected static class MetadataTransferRestTemplateConfig { @Bean - public EncodeTransferMedataRestTemplateEnhancedPlugin encodeTransferMedataRestTemplateEnhancedPlugin() { - return new EncodeTransferMedataRestTemplateEnhancedPlugin(); + public EncodeTransferMedataRestTemplateEnhancedPlugin encodeTransferMedataRestTemplateEnhancedPlugin( + @Autowired(required = false) List contextToHeaderInterceptorList) { + return new EncodeTransferMedataRestTemplateEnhancedPlugin(contextToHeaderInterceptorList); } } @@ -134,8 +141,9 @@ public class MetadataTransferAutoConfiguration { protected static class MetadataTransferWebClientConfig { @Bean - public EncodeTransferMedataWebClientEnhancedPlugin encodeTransferMedataWebClientEnhancedPlugin() { - return new EncodeTransferMedataWebClientEnhancedPlugin(); + public EncodeTransferMedataWebClientEnhancedPlugin encodeTransferMedataWebClientEnhancedPlugin( + @Autowired(required = false) List contextToHeaderInterceptorList) { + return new EncodeTransferMedataWebClientEnhancedPlugin(contextToHeaderInterceptorList); } } } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignEnhancedPlugin.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignEnhancedPlugin.java index 3a8aca42c..b2c09f31f 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignEnhancedPlugin.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataFeignEnhancedPlugin.java @@ -19,8 +19,11 @@ package com.tencent.cloud.metadata.core; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import java.util.Optional; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.MetadataContextHolder; @@ -38,6 +41,7 @@ import com.tencent.polaris.metadata.core.MetadataType; import feign.Request; import shade.polaris.com.google.common.collect.ImmutableMap; +import org.springframework.tsf.core.filter.ContextToHeaderInterceptor; import org.springframework.util.CollectionUtils; import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.APPLICATION_METADATA; @@ -50,6 +54,13 @@ import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUST * @author Shedfree Wu */ public class EncodeTransferMedataFeignEnhancedPlugin implements EnhancedPlugin { + + private List contextToHeaderInterceptorList; + + public EncodeTransferMedataFeignEnhancedPlugin(List contextToHeaderInterceptorList) { + this.contextToHeaderInterceptorList = Optional.ofNullable(contextToHeaderInterceptorList).orElse(Collections.EMPTY_LIST); + } + @Override public EnhancedPluginType getType() { return EnhancedPluginType.Client.PRE; @@ -61,6 +72,7 @@ public class EncodeTransferMedataFeignEnhancedPlugin implements EnhancedPlugin { return; } Request request = (Request) context.getOriginRequest(); + contextToHeaderInterceptorList.forEach(ContextToHeaderInterceptor::beforeContextToHeader); // get metadata of current thread MetadataContext metadataContext = MetadataContextHolder.get(); @@ -89,6 +101,8 @@ public class EncodeTransferMedataFeignEnhancedPlugin implements EnhancedPlugin { // set headers that need to be transmitted from the upstream this.buildTransmittedHeader(request, transHeaders); + + contextToHeaderInterceptorList.forEach(ContextToHeaderInterceptor::afterContextToHeader); } private void buildTransmittedHeader(Request request, Map transHeaders) { diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateEnhancedPlugin.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateEnhancedPlugin.java index cd5af6b7b..8363b995c 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateEnhancedPlugin.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataRestTemplateEnhancedPlugin.java @@ -17,7 +17,10 @@ package com.tencent.cloud.metadata.core; +import java.util.Collections; +import java.util.List; import java.util.Map; +import java.util.Optional; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.MetadataContextHolder; @@ -34,6 +37,7 @@ import com.tencent.polaris.metadata.core.MetadataType; import shade.polaris.com.google.common.collect.ImmutableMap; import org.springframework.http.HttpRequest; +import org.springframework.tsf.core.filter.ContextToHeaderInterceptor; import org.springframework.util.CollectionUtils; import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.APPLICATION_METADATA; @@ -46,6 +50,13 @@ import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUST * @author Shedfree Wu */ public class EncodeTransferMedataRestTemplateEnhancedPlugin implements EnhancedPlugin { + + private List contextToHeaderInterceptorList; + + public EncodeTransferMedataRestTemplateEnhancedPlugin(List contextToHeaderInterceptorList) { + this.contextToHeaderInterceptorList = Optional.ofNullable(contextToHeaderInterceptorList).orElse(Collections.EMPTY_LIST); + } + @Override public EnhancedPluginType getType() { return EnhancedPluginType.Client.BEFORE_CALLING; @@ -58,6 +69,8 @@ public class EncodeTransferMedataRestTemplateEnhancedPlugin implements EnhancedP } HttpRequest httpRequest = (HttpRequest) context.getOriginRequest(); + contextToHeaderInterceptorList.forEach(ContextToHeaderInterceptor::beforeContextToHeader); + // get metadata of current thread MetadataContext metadataContext = MetadataContextHolder.get(); Map customMetadata = metadataContext.getCustomMetadata(); @@ -86,6 +99,8 @@ public class EncodeTransferMedataRestTemplateEnhancedPlugin implements EnhancedP // set headers that need to be transmitted from the upstream this.buildTransmittedHeader(httpRequest, transHeaders); + + contextToHeaderInterceptorList.forEach(ContextToHeaderInterceptor::afterContextToHeader); } private void buildTransmittedHeader(HttpRequest request, Map transHeaders) { diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgEnhancedPlugin.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgEnhancedPlugin.java index bab976cc6..c5f554015 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgEnhancedPlugin.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgEnhancedPlugin.java @@ -17,7 +17,10 @@ package com.tencent.cloud.metadata.core; +import java.util.Collections; +import java.util.List; import java.util.Map; +import java.util.Optional; import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.common.metadata.MetadataContext; @@ -35,6 +38,7 @@ import com.tencent.polaris.metadata.core.MetadataType; import shade.polaris.com.google.common.collect.ImmutableMap; import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.tsf.core.filter.ContextToHeaderInterceptor; import org.springframework.util.CollectionUtils; import org.springframework.web.server.ServerWebExchange; @@ -48,6 +52,13 @@ import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUST * @author Shedfree Wu */ public class EncodeTransferMedataScgEnhancedPlugin implements EnhancedPlugin { + + private List contextToHeaderInterceptorList; + + public EncodeTransferMedataScgEnhancedPlugin(List contextToHeaderInterceptorList) { + this.contextToHeaderInterceptorList = Optional.ofNullable(contextToHeaderInterceptorList).orElse(Collections.EMPTY_LIST); + } + @Override public EnhancedPluginType getType() { return EnhancedPluginType.Client.PRE; @@ -69,6 +80,8 @@ public class EncodeTransferMedataScgEnhancedPlugin implements EnhancedPlugin { metadataContext = MetadataContextHolder.get(); } + contextToHeaderInterceptorList.forEach(ContextToHeaderInterceptor::beforeContextToHeader); + Map customMetadata = metadataContext.getCustomMetadata(); Map disposableMetadata = metadataContext.getDisposableMetadata(); Map applicationMetadata = metadataContext.getApplicationMetadata(); @@ -86,6 +99,8 @@ public class EncodeTransferMedataScgEnhancedPlugin implements EnhancedPlugin { this.buildMetadataHeader(builder, applicationMetadata, APPLICATION_METADATA); TransHeadersTransfer.transfer(exchange.getRequest()); + contextToHeaderInterceptorList.forEach(ContextToHeaderInterceptor::afterContextToHeader); + context.setOriginRequest(exchange.mutate().request(builder.build()).build()); } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataWebClientEnhancedPlugin.java b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataWebClientEnhancedPlugin.java index ef71312eb..3e5c28085 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataWebClientEnhancedPlugin.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/main/java/com/tencent/cloud/metadata/core/EncodeTransferMedataWebClientEnhancedPlugin.java @@ -17,7 +17,10 @@ package com.tencent.cloud.metadata.core; +import java.util.Collections; +import java.util.List; import java.util.Map; +import java.util.Optional; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.MetadataContextHolder; @@ -33,6 +36,7 @@ import com.tencent.polaris.metadata.core.MessageMetadataContainer; import com.tencent.polaris.metadata.core.MetadataType; import shade.polaris.com.google.common.collect.ImmutableMap; +import org.springframework.tsf.core.filter.ContextToHeaderInterceptor; import org.springframework.util.CollectionUtils; import org.springframework.web.reactive.function.client.ClientRequest; @@ -46,6 +50,13 @@ import static com.tencent.cloud.common.constant.MetadataConstant.HeaderName.CUST * @author Shedfree Wu */ public class EncodeTransferMedataWebClientEnhancedPlugin implements EnhancedPlugin { + + private List contextToHeaderInterceptorList; + + public EncodeTransferMedataWebClientEnhancedPlugin(List contextToHeaderInterceptorList) { + this.contextToHeaderInterceptorList = Optional.ofNullable(contextToHeaderInterceptorList).orElse(Collections.EMPTY_LIST); + } + @Override public EnhancedPluginType getType() { return EnhancedPluginType.Client.PRE; @@ -56,6 +67,8 @@ public class EncodeTransferMedataWebClientEnhancedPlugin implements EnhancedPlug if (!(context.getOriginRequest() instanceof ClientRequest)) { return; } + contextToHeaderInterceptorList.forEach(ContextToHeaderInterceptor::beforeContextToHeader); + ClientRequest clientRequest = (ClientRequest) context.getOriginRequest(); MetadataContext metadataContext = MetadataContextHolder.get(); @@ -77,6 +90,9 @@ public class EncodeTransferMedataWebClientEnhancedPlugin implements EnhancedPlug this.buildMetadataHeader(requestBuilder, disposableMetadata, CUSTOM_DISPOSABLE_METADATA); this.buildMetadataHeader(requestBuilder, applicationMetadata, APPLICATION_METADATA); this.buildTransmittedHeader(requestBuilder, transHeaders); + + contextToHeaderInterceptorList.forEach(ContextToHeaderInterceptor::beforeContextToHeader); + context.setOriginRequest(requestBuilder.build()); } diff --git a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java index 84331bbef..1909578cd 100644 --- a/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java +++ b/spring-cloud-starter-tencent-metadata-transfer/src/test/java/com/tencent/cloud/metadata/core/EncodeTransferMedataScgFilterTest.java @@ -19,6 +19,7 @@ package com.tencent.cloud.metadata.core; import java.net.URI; import java.net.URISyntaxException; +import java.util.ArrayList; import java.util.Arrays; import com.tencent.cloud.common.constant.MetadataConstant; @@ -114,7 +115,7 @@ public class EncodeTransferMedataScgFilterTest { MockServerHttpRequest mockServerHttpRequest = MockServerHttpRequest.get("/test").build(); - EncodeTransferMedataScgEnhancedPlugin plugin = new EncodeTransferMedataScgEnhancedPlugin(); + EncodeTransferMedataScgEnhancedPlugin plugin = new EncodeTransferMedataScgEnhancedPlugin(new ArrayList<>()); plugin.getOrder(); EnhancedGatewayGlobalFilter filter = new EnhancedGatewayGlobalFilter(new DefaultEnhancedPluginRunner(Arrays.asList(plugin), registration, null)); filter.getOrder(); diff --git a/spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/filter/ContextToHeaderInterceptor.java b/spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/filter/ContextToHeaderInterceptor.java new file mode 100644 index 000000000..1a46ea1c3 --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/filter/ContextToHeaderInterceptor.java @@ -0,0 +1,30 @@ +/* + * Tencent is pleased to support the open source community by making spring-cloud-tencent available. + * + * Copyright (C) 2021 Tencent. 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 org.springframework.tsf.core.filter; + +/** + * Compatible with old versions TSF SDK. + * + * @author Shedfree Wu + */ +public interface ContextToHeaderInterceptor { + + void beforeContextToHeader(); + + void afterContextToHeader(); +} diff --git a/spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/util/TagUtils.java b/spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/util/TagUtils.java new file mode 100644 index 000000000..0af8120bb --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/util/TagUtils.java @@ -0,0 +1,64 @@ +/* + * Tencent is pleased to support the open source community by making spring-cloud-tencent available. + * + * Copyright (C) 2021 Tencent. 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 org.springframework.tsf.core.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.tencent.cloud.common.util.JacksonUtils; +import com.tencent.cloud.common.util.TsfTagUtils; + +import org.springframework.tsf.core.entity.Metadata; +import org.springframework.tsf.core.entity.Tag; + +/** + * Compatible with old versions TSF SDK. + * + * @author Shedfree Wu + */ +public final class TagUtils { + + private TagUtils() { + } + + public static String serializeToJson(T object) { + return JacksonUtils.serialize2Json(object); + } + + public static List deserializeTagList(String buffer) { + return TsfTagUtils.deserializeTagList(buffer); + } + + public static Metadata deserializeMetadata(String buffer) { + return TsfTagUtils.deserializeMetadata(buffer); + } + + public static List getTagListFromTagMap(Map tagMap) { + return new ArrayList<>(tagMap.values()); + } + + public static Map buildTagMapFromTagList(List tagList) { + Map result = new HashMap<>(); + for (Tag tag : tagList) { + result.put(tag.getKey(), tag); + } + return result; + } +} diff --git a/spring-cloud-tencent-commons/src/test/java/org/springframework/tsf/core/util/TagUtilsTest.java b/spring-cloud-tencent-commons/src/test/java/org/springframework/tsf/core/util/TagUtilsTest.java new file mode 100644 index 000000000..4d582c1fe --- /dev/null +++ b/spring-cloud-tencent-commons/src/test/java/org/springframework/tsf/core/util/TagUtilsTest.java @@ -0,0 +1,92 @@ +/* + * Tencent is pleased to support the open source community by making spring-cloud-tencent available. + * + * Copyright (C) 2021 Tencent. 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 org.springframework.tsf.core.util; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import com.tencent.cloud.common.util.JacksonUtils; +import com.tencent.cloud.common.util.TsfTagUtils; +import com.tencent.cloud.common.util.UrlUtils; +import org.junit.jupiter.api.Test; + +import org.springframework.tsf.core.entity.Metadata; +import org.springframework.tsf.core.entity.Tag; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link TagUtils}. + */ +public class TagUtilsTest { + + @Test + public void testSerializeDeserialize() { + Tag tag = new Tag("key", "value"); + String json = TagUtils.serializeToJson(Collections.singletonList(tag)); + + List tagList = TagUtils.deserializeTagList(json); + assertThat(tagList).isEqualTo(Collections.singletonList(tag)); + } + + @Test + public void testBuildTagMapFromTagList() { + Tag tag = new Tag("key", "value"); + List tagList = Collections.singletonList(tag); + Map tagMap = TagUtils.buildTagMapFromTagList(tagList); + List tagList2 = TagUtils.getTagListFromTagMap(tagMap); + + assertThat(tagList2).isEqualTo(tagList); + } + + @Test + public void testDeserializeMetadata() { + String encodedInput = "%7B%22ai%22%3A%22applicationId%22%2C%22av%22%3A%22applicationVersion%22%2C%22sn%22%3A%22serviceName%22%2C%22ii%22%3A%22instanceId%22%2C%22gi%22%3A%22groupId%22%2C%22li%22%3A%22127.0.0.1%22%2C%22lis%22%3A%22127.0.0.1%22%2C%22ni%22%3A%22namespaceId%22%2C%22pi%22%3Atrue%7D"; + Metadata expectedMetadata = new Metadata(); + expectedMetadata.setApplicationId("applicationId"); + expectedMetadata.setApplicationVersion("applicationVersion"); + expectedMetadata.setServiceName("serviceName"); + expectedMetadata.setInstanceId("instanceId"); + expectedMetadata.setGroupId("groupId"); + expectedMetadata.setLocalIp("127.0.0.1"); + expectedMetadata.setLocalIps("127.0.0.1"); + expectedMetadata.setNamespaceId("namespaceId"); + expectedMetadata.setPreferIpv6(true); + + String json = JacksonUtils.serialize2Json(expectedMetadata); + String buffer = UrlUtils.encode(json); + System.out.println(buffer); + + Metadata result = TagUtils.deserializeMetadata(encodedInput); + assertThat(result).isNotNull(); + assertThat(result.toString()).isEqualTo(expectedMetadata.toString()); + assertThat(result.getApplicationId()).isEqualTo(expectedMetadata.getApplicationId()); + assertThat(result.getApplicationVersion()).isEqualTo(expectedMetadata.getApplicationVersion()); + assertThat(result.getServiceName()).isEqualTo(expectedMetadata.getServiceName()); + assertThat(result.getInstanceId()).isEqualTo(expectedMetadata.getInstanceId()); + assertThat(result.getGroupId()).isEqualTo(expectedMetadata.getGroupId()); + assertThat(result.getLocalIp()).isEqualTo(expectedMetadata.getLocalIp()); + assertThat(result.getLocalIps()).isEqualTo(expectedMetadata.getLocalIps()); + assertThat(result.getNamespaceId()).isEqualTo(expectedMetadata.getNamespaceId()); + assertThat(result.isPreferIpv6()).isEqualTo(expectedMetadata.isPreferIpv6()); + + assertThat(TsfTagUtils.deserializeMetadata(null)).isNull(); + assertThat(TsfTagUtils.deserializeMetadata("")).isNull(); + } +} diff --git a/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/TestContextToHeaderInterceptor.java b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/TestContextToHeaderInterceptor.java new file mode 100644 index 000000000..73071626a --- /dev/null +++ b/spring-cloud-tencent-examples/tsf-example/consumer-demo/src/main/java/com/tencent/cloud/tsf/demo/consumer/TestContextToHeaderInterceptor.java @@ -0,0 +1,40 @@ +/* + * Tencent is pleased to support the open source community by making spring-cloud-tencent available. + * + * Copyright (C) 2021 Tencent. 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.tsf.demo.consumer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.stereotype.Component; +import org.springframework.tsf.core.filter.ContextToHeaderInterceptor; + +@Component +public class TestContextToHeaderInterceptor implements ContextToHeaderInterceptor { + + private static final Logger LOG = LoggerFactory.getLogger(TestContextToHeaderInterceptor.class); + + @Override + public void beforeContextToHeader() { + LOG.info("beforeContextToHeader"); + } + + @Override + public void afterContextToHeader() { + LOG.info("afterContextToHeader"); + } +} diff --git a/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/ProviderController.java b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/ProviderController.java index 99be7792f..bc842addf 100644 --- a/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/ProviderController.java +++ b/spring-cloud-tencent-examples/tsf-example/provider-demo/src/main/java/com/tencent/cloud/tsf/demo/provider/ProviderController.java @@ -20,8 +20,10 @@ import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; +import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; +import java.util.List; import java.util.Map; import com.tencent.cloud.tsf.demo.provider.config.ProviderNameConfig; @@ -33,6 +35,9 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; +import org.springframework.tsf.core.entity.Tag; +import org.springframework.tsf.core.util.TagUtils; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -194,4 +199,14 @@ public class ProviderController { LOG.info("provider-demo -- response info: [" + resultMap + "]"); return resultMap; } + + @GetMapping("/tagUtils") + public String tagUtils(@RequestParam("key") String key, @RequestParam("value") String value) { + Tag tag = new Tag(key, value); + String json = TagUtils.serializeToJson(Collections.singletonList(tag)); + + List tagList = TagUtils.deserializeTagList(json); + + return "serializeToJson: " + json + ", deserializeTagList: " + tagList; + } }