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 +
+ '}';
+ }
+}