From b09e8b33b44b03a91952c19eac32d01fc945a2c0 Mon Sep 17 00:00:00 2001 From: andrewshan Date: Sun, 16 Jun 2024 22:36:36 +0800 Subject: [PATCH] feat: add tsfContext adaptive --- spring-cloud-tencent-commons/pom.xml | 5 + .../common/metadata/MetadataContext.java | 2 +- .../tsf/core/context/TsfContext.java | 77 +++++++++ .../springframework/tsf/core/entity/Tag.java | 148 ++++++++++++++++++ 4 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/context/TsfContext.java create mode 100644 spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/entity/Tag.java diff --git a/spring-cloud-tencent-commons/pom.xml b/spring-cloud-tencent-commons/pom.xml index a667b9831..59daa7efe 100644 --- a/spring-cloud-tencent-commons/pom.xml +++ b/spring-cloud-tencent-commons/pom.xml @@ -78,6 +78,11 @@ true + + com.google.code.gson + gson + + org.springframework.cloud spring-cloud-starter-openfeign 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 f398d3147..e43a60f86 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 @@ -137,7 +137,7 @@ public class MetadataContext extends com.tencent.polaris.metadata.core.manager.M return values; } - private void putMetadataAsMap(MetadataType metadataType, TransitiveType transitiveType, boolean downstream, Map values) { + public void putMetadataAsMap(MetadataType metadataType, TransitiveType transitiveType, boolean downstream, Map values) { MetadataContainer metadataContainer = getMetadataContainer(metadataType, downstream); for (Map.Entry entry : values.entrySet()) { metadataContainer.putMetadataStringValue(entry.getKey(), entry.getValue(), transitiveType); diff --git a/spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/context/TsfContext.java b/spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/context/TsfContext.java new file mode 100644 index 000000000..6fa988e19 --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/context/TsfContext.java @@ -0,0 +1,77 @@ +/* + * 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 org.springframework.tsf.core.context; + +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.Map; + +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.metadata.MetadataContextHolder; +import com.tencent.polaris.metadata.core.MetadataType; +import com.tencent.polaris.metadata.core.TransitiveType; + +import org.springframework.tsf.core.entity.Tag; + +public class TsfContext { + + private static class Limit { + static final int MAX_KEY_LENGTH = 32; + static final int MAX_VALUE_LENGTH = 128; + } + + public static void putTags(Map tagMap, Tag.ControlFlag... flags) { + if (tagMap == null) { + return; + } + MetadataContext tsfCoreContext = MetadataContextHolder.get(); + TransitiveType transitive = TransitiveType.NONE; + if (null != flags) { + for (Tag.ControlFlag flag : flags) { + if (flag == Tag.ControlFlag.TRANSITIVE) { + transitive = TransitiveType.PASS_THROUGH; + break; + } + } + } + for (Map.Entry entry : tagMap.entrySet()) { + validateTag(entry.getKey(), entry.getValue()); + } + tsfCoreContext.putMetadataAsMap(MetadataType.CUSTOM, transitive, false, tagMap); + } + + public static void putTag(String key, String value, Tag.ControlFlag... flags) { + putTags(Collections.singletonMap(key, value), flags); + } + + private static void validateTag(String key, String value) { + int keyLength, valueLength; + keyLength = key.getBytes(StandardCharsets.UTF_8).length; + valueLength = value.getBytes(StandardCharsets.UTF_8).length; + + if (keyLength > Limit.MAX_KEY_LENGTH) { + throw new RuntimeException(String.format("Key \"%s\" length (after UTF-8 encoding) exceeding limit (%d)", key, + Limit.MAX_KEY_LENGTH)); + } + if (valueLength > Limit.MAX_VALUE_LENGTH) { + throw new RuntimeException(String.format("Value \"%s\" length (after UTF-8 encoding) exceeding limit (%d)", value, + Limit.MAX_VALUE_LENGTH)); + } + } +} diff --git a/spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/entity/Tag.java b/spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/entity/Tag.java new file mode 100644 index 000000000..c714ca7f1 --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/org/springframework/tsf/core/entity/Tag.java @@ -0,0 +1,148 @@ +/* + * 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 org.springframework.tsf.core.entity; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class Tag implements Serializable { + // 每次对这个结构的 JSON 序列化结果有改动时,必须修改 VERSION 并写兼容性代码 + public static final int VERSION = 1; + + public enum ControlFlag { + /** + * 表示标签要在调用中传递下去,默认不启用 + */ + @SerializedName("0") + TRANSITIVE, + + /** + * 表示标签不被使用在服务鉴权,默认是被使用的 + */ + @SerializedName("1") + NOT_IN_AUTH, + + /** + * 表示标签不被使用在服务路由,默认是被使用的 + */ + @SerializedName("2") + NOT_IN_ROUTE, + + /** + * 表示标签不被使用在调用链,默认是被使用的 + */ + @SerializedName("3") + NOT_IN_SLEUTH, + + /** + * 表示标签不被使用在调用链,默认是被使用的 + */ + @SerializedName("4") + NOT_IN_LANE, + + /** + * 表示标签被使用在单元化场景,默认是不被使用的 + */ + @SerializedName("5") + IN_UNIT + } + + public enum Scene { + /** + * 不限场景 + */ + NO_SPECIFIC, + AUTH, ROUTE, SLEUTH, LANE, UNIT + } + + @SerializedName("k") + @Expose + private String key; + + @SerializedName("v") + @Expose + private String value; + + @SerializedName("f") + @Expose + private Set flags = new HashSet<>(); + + public Tag(String key, String value, ControlFlag... flags) { + this.key = key; + this.value = value; + this.flags = new HashSet<>(Arrays.asList(flags)); + } + + public Tag() { + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public Set getFlags() { + return flags; + } + + public void setFlags(Set flags) { + this.flags = flags; + } + + @Override + public boolean equals(Object object) { + if (object instanceof Tag) { + Tag tag = (Tag) object; + return (key == null ? tag.key == null : key.equals(tag.key)) + && (flags == null ? tag.flags == null : flags.equals(tag.flags)); + } + return false; + } + + @Override + public int hashCode() { + return (key == null ? 0 : key.hashCode()) + (flags == null ? 0 : flags.hashCode()); + } + + + @Override + public String toString() { + return "Tag{" + + "key='" + key + '\'' + + ", value='" + value + '\'' + + ", flags=" + flags + + '}'; + } +}