feat: SCT元数据管理能力与polaris-java元数据管理能力进行下沉及整合 (#1249)

pull/1250/head
andrew shan 1 year ago committed by GitHub
parent c54875bea4
commit 9f0a2825a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -24,6 +24,10 @@
<groupId>com.tencent.polaris</groupId> <groupId>com.tencent.polaris</groupId>
<artifactId>polaris-model</artifactId> <artifactId>polaris-model</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-metadata</artifactId>
</dependency>
<!-- Polaris dependencies end --> <!-- Polaris dependencies end -->
<dependency> <dependency>

@ -21,22 +21,25 @@ package com.tencent.cloud.common.metadata;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.Optional;
import java.util.function.BiConsumer;
import com.tencent.cloud.common.constant.MetadataConstant;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.common.util.DiscoveryUtil; import com.tencent.cloud.common.util.DiscoveryUtil;
import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.polaris.metadata.core.MetadataContainer;
import com.tencent.polaris.metadata.core.MetadataMapValue;
import com.tencent.polaris.metadata.core.MetadataObjectValue;
import com.tencent.polaris.metadata.core.MetadataStringValue;
import com.tencent.polaris.metadata.core.MetadataType;
import com.tencent.polaris.metadata.core.MetadataValue;
import com.tencent.polaris.metadata.core.TransitiveType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** public class MetadataContext extends com.tencent.polaris.metadata.core.manager.MetadataContext {
* Metadata Context.
*
* @author Haotian Zhang
*/
public class MetadataContext {
/** /**
* transitive context. * transitive context.
@ -63,6 +66,11 @@ public class MetadataContext {
*/ */
public static final String FRAGMENT_RAW_TRANSHEADERS_KV = "trans-headers-kv"; public static final String FRAGMENT_RAW_TRANSHEADERS_KV = "trans-headers-kv";
/**
* the key of the header(key-value) list needed to be store as loadbalance data.
*/
public static final String FRAGMENT_LB_METADATA = "load-balance-metadata";
private static final Logger LOG = LoggerFactory.getLogger(MetadataContext.class); private static final Logger LOG = LoggerFactory.getLogger(MetadataContext.class);
/** /**
* Namespace of local instance. * Namespace of local instance.
@ -108,22 +116,70 @@ public class MetadataContext {
LOCAL_SERVICE = serviceName; LOCAL_SERVICE = serviceName;
} }
private final Map<String, Map<String, String>> fragmentContexts; public MetadataContext() {
super(MetadataConstant.POLARIS_TRANSITIVE_HEADER_PREFIX);
}
private final Map<String, Object> loadbalancerMetadata; private Map<String, String> getMetadataAsMap(MetadataType metadataType, TransitiveType transitiveType, boolean downstream) {
MetadataContainer metadataContainer = getMetadataContainer(metadataType, downstream);
Map<String, String> values = new HashMap<>();
metadataContainer.iterateMetadataValues(new BiConsumer<String, MetadataValue>() {
@Override
public void accept(String s, MetadataValue metadataValue) {
if (metadataValue instanceof MetadataStringValue) {
MetadataStringValue metadataStringValue = (MetadataStringValue) metadataValue;
if (metadataStringValue.getTransitiveType() == transitiveType) {
values.put(s, metadataStringValue.getStringValue());
}
}
}
});
return values;
}
private void putMetadataAsMap(MetadataType metadataType, TransitiveType transitiveType, boolean downstream, Map<String, String> values) {
MetadataContainer metadataContainer = getMetadataContainer(metadataType, downstream);
for (Map.Entry<String, String> entry : values.entrySet()) {
metadataContainer.putMetadataStringValue(entry.getKey(), entry.getValue(), transitiveType);
}
}
public MetadataContext() { private Map<String, String> getMapMetadataAsMap(MetadataType metadataType, String mapKey, TransitiveType transitiveType, boolean downstream) {
this.fragmentContexts = new ConcurrentHashMap<>(); MetadataContainer metadataContainer = getMetadataContainer(metadataType, downstream);
this.loadbalancerMetadata = new ConcurrentHashMap<>(); Map<String, String> values = new HashMap<>();
MetadataValue metadataValue = metadataContainer.getMetadataValue(mapKey);
if (!(metadataValue instanceof MetadataMapValue)) {
return values;
}
MetadataMapValue metadataMapValue = (MetadataMapValue) metadataValue;
metadataMapValue.iterateMapValues(new BiConsumer<String, MetadataValue>() {
@Override
public void accept(String s, MetadataValue metadataValue) {
if (metadataValue instanceof MetadataStringValue) {
MetadataStringValue metadataStringValue = (MetadataStringValue) metadataValue;
if (metadataStringValue.getTransitiveType() == transitiveType) {
values.put(s, metadataStringValue.getStringValue());
}
}
}
});
return values;
}
private void putMapMetadataAsMap(MetadataType metadataType, String mapKey,
TransitiveType transitiveType, boolean downstream, Map<String, String> values) {
MetadataContainer metadataContainer = getMetadataContainer(metadataType, downstream);
for (Map.Entry<String, String> entry : values.entrySet()) {
metadataContainer.putMetadataMapValue(mapKey, entry.getKey(), entry.getValue(), transitiveType);
}
} }
public Map<String, String> getDisposableMetadata() { public Map<String, String> getDisposableMetadata() {
return this.getFragmentContext(MetadataContext.FRAGMENT_DISPOSABLE); return getFragmentContext(FRAGMENT_DISPOSABLE);
} }
public Map<String, String> getTransitiveMetadata() { public Map<String, String> getTransitiveMetadata() {
return this.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); return getFragmentContext(FRAGMENT_TRANSITIVE);
} }
public Map<String, String> getCustomMetadata() { public Map<String, String> getCustomMetadata() {
@ -140,51 +196,76 @@ public class MetadataContext {
} }
public Map<String, String> getTransHeaders() { public Map<String, String> getTransHeaders() {
return this.getFragmentContext(MetadataContext.FRAGMENT_RAW_TRANSHEADERS); return this.getFragmentContext(FRAGMENT_RAW_TRANSHEADERS);
} }
public Map<String, String> getTransHeadersKV() { public Map<String, String> getTransHeadersKV() {
return this.getFragmentContext(MetadataContext.FRAGMENT_RAW_TRANSHEADERS_KV); return getFragmentContext(FRAGMENT_RAW_TRANSHEADERS_KV);
} }
public Map<String, Object> getLoadbalancerMetadata() { public Map<String, Object> getLoadbalancerMetadata() {
return this.loadbalancerMetadata; MetadataContainer metadataContainer = getMetadataContainer(MetadataType.APPLICATION, false);
MetadataValue metadataValue = metadataContainer.getMetadataValue(FRAGMENT_LB_METADATA);
Map<String, Object> values = new HashMap<>();
if (metadataValue instanceof MetadataMapValue) {
MetadataMapValue metadataMapValue = (MetadataMapValue) metadataValue;
metadataMapValue.iterateMapValues(new BiConsumer<String, MetadataValue>() {
@Override
public void accept(String s, MetadataValue metadataValue) {
if (metadataValue instanceof MetadataObjectValue) {
Optional<?> objectValue = ((MetadataObjectValue<?>) metadataValue).getObjectValue();
objectValue.ifPresent(o -> values.put(s, o));
}
}
});
}
return values;
}
public void setLoadbalancer(String key, Object value) {
MetadataContainer metadataContainer = getMetadataContainer(MetadataType.APPLICATION, false);
metadataContainer.putMetadataMapObjectValue(FRAGMENT_LB_METADATA, key, value);
} }
public void setTransitiveMetadata(Map<String, String> transitiveMetadata) { public void setTransitiveMetadata(Map<String, String> transitiveMetadata) {
this.putFragmentContext(FRAGMENT_TRANSITIVE, Collections.unmodifiableMap(transitiveMetadata)); putFragmentContext(FRAGMENT_TRANSITIVE, Collections.unmodifiableMap(transitiveMetadata));
} }
public void setDisposableMetadata(Map<String, String> disposableMetadata) { public void setDisposableMetadata(Map<String, String> disposableMetadata) {
this.putFragmentContext(FRAGMENT_DISPOSABLE, Collections.unmodifiableMap(disposableMetadata)); putFragmentContext(FRAGMENT_DISPOSABLE, Collections.unmodifiableMap(disposableMetadata));
} }
public void setUpstreamDisposableMetadata(Map<String, String> upstreamDisposableMetadata) { public void setUpstreamDisposableMetadata(Map<String, String> upstreamDisposableMetadata) {
this.putFragmentContext(FRAGMENT_UPSTREAM_DISPOSABLE, Collections.unmodifiableMap(upstreamDisposableMetadata)); putFragmentContext(FRAGMENT_UPSTREAM_DISPOSABLE, Collections.unmodifiableMap(upstreamDisposableMetadata));
} }
public void setTransHeadersKV(String key, String value) { public void setTransHeadersKV(String key, String value) {
this.putContext(FRAGMENT_RAW_TRANSHEADERS_KV, key, value); putContext(FRAGMENT_RAW_TRANSHEADERS_KV, key, value);
} }
public void setTransHeaders(String key, String value) { public void setTransHeaders(String key, String value) {
this.putContext(FRAGMENT_RAW_TRANSHEADERS, key, value); putContext(FRAGMENT_RAW_TRANSHEADERS, key, value);
}
public void setLoadbalancer(String key, Object value) {
this.loadbalancerMetadata.put(key, value);
} }
public Map<String, String> getFragmentContext(String fragment) { public Map<String, String> getFragmentContext(String fragment) {
Map<String, String> fragmentContext = fragmentContexts.get(fragment); switch (fragment) {
if (fragmentContext == null) { case FRAGMENT_TRANSITIVE:
return Collections.emptyMap(); return getMetadataAsMap(MetadataType.CUSTOM, TransitiveType.PASS_THROUGH, false);
case FRAGMENT_DISPOSABLE:
return getMetadataAsMap(MetadataType.CUSTOM, TransitiveType.DISPOSABLE, false);
case FRAGMENT_UPSTREAM_DISPOSABLE:
return getMetadataAsMap(MetadataType.CUSTOM, TransitiveType.DISPOSABLE, true);
case FRAGMENT_RAW_TRANSHEADERS:
return getMapMetadataAsMap(MetadataType.CUSTOM, FRAGMENT_RAW_TRANSHEADERS, TransitiveType.NONE, false);
case FRAGMENT_RAW_TRANSHEADERS_KV:
return getMapMetadataAsMap(MetadataType.CUSTOM, FRAGMENT_RAW_TRANSHEADERS_KV, TransitiveType.PASS_THROUGH, false);
default:
return getMapMetadataAsMap(MetadataType.CUSTOM, fragment, TransitiveType.NONE, false);
} }
return Collections.unmodifiableMap(fragmentContext);
} }
public String getContext(String fragment, String key) { public String getContext(String fragment, String key) {
Map<String, String> fragmentContext = fragmentContexts.get(fragment); Map<String, String> fragmentContext = getFragmentContext(fragment);
if (fragmentContext == null) { if (fragmentContext == null) {
return null; return null;
} }
@ -192,22 +273,32 @@ public class MetadataContext {
} }
public void putContext(String fragment, String key, String value) { public void putContext(String fragment, String key, String value) {
Map<String, String> fragmentContext = fragmentContexts.get(fragment); Map<String, String> values = new HashMap<>();
if (fragmentContext == null) { values.put(key, value);
fragmentContext = new ConcurrentHashMap<>(); putFragmentContext(fragment, values);
fragmentContexts.put(fragment, fragmentContext);
}
fragmentContext.put(key, value);
} }
public void putFragmentContext(String fragment, Map<String, String> context) { public void putFragmentContext(String fragment, Map<String, String> context) {
fragmentContexts.put(fragment, context); switch (fragment) {
case FRAGMENT_TRANSITIVE:
putMetadataAsMap(MetadataType.CUSTOM, TransitiveType.PASS_THROUGH, false, context);
break;
case FRAGMENT_DISPOSABLE:
putMetadataAsMap(MetadataType.CUSTOM, TransitiveType.DISPOSABLE, false, context);
break;
case FRAGMENT_UPSTREAM_DISPOSABLE:
putMetadataAsMap(MetadataType.CUSTOM, TransitiveType.DISPOSABLE, true, context);
break;
case FRAGMENT_RAW_TRANSHEADERS:
putMapMetadataAsMap(MetadataType.CUSTOM, FRAGMENT_RAW_TRANSHEADERS, TransitiveType.NONE, false, context);
break;
case FRAGMENT_RAW_TRANSHEADERS_KV:
putMapMetadataAsMap(MetadataType.CUSTOM, FRAGMENT_RAW_TRANSHEADERS_KV, TransitiveType.PASS_THROUGH, false, context);
break;
default:
putMapMetadataAsMap(MetadataType.CUSTOM, fragment, TransitiveType.NONE, false, context);
break;
} }
@Override
public String toString() {
return "MetadataContext{" +
"fragmentContexts=" + JacksonUtils.serialize2Json(fragmentContexts) +
'}';
} }
} }

@ -24,6 +24,9 @@ import java.util.Optional;
import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.polaris.metadata.core.MetadataContainer;
import com.tencent.polaris.metadata.core.MetadataType;
import com.tencent.polaris.metadata.core.TransitiveType;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -38,8 +41,6 @@ import static com.tencent.cloud.common.metadata.MetadataContext.FRAGMENT_UPSTREA
*/ */
public final class MetadataContextHolder { public final class MetadataContextHolder {
private static final ThreadLocal<MetadataContext> METADATA_CONTEXT = new InheritableThreadLocal<>();
private static MetadataLocalProperties metadataLocalProperties; private static MetadataLocalProperties metadataLocalProperties;
private static StaticMetadataManager staticMetadataManager; private static StaticMetadataManager staticMetadataManager;
@ -47,38 +48,41 @@ public final class MetadataContextHolder {
private MetadataContextHolder() { private MetadataContextHolder() {
} }
/**
* Get metadata context. Create if not existing.
* @return METADATA_CONTEXT
*/
public static MetadataContext get() { public static MetadataContext get() {
if (METADATA_CONTEXT.get() != null) { return (MetadataContext) com.tencent.polaris.metadata.core.manager.MetadataContextHolder.getOrCreate(
return METADATA_CONTEXT.get(); MetadataContextHolder::createMetadataManager);
} }
private static MetadataContext createMetadataManager() {
MetadataContext metadataManager = new MetadataContext();
if (metadataLocalProperties == null) { if (metadataLocalProperties == null) {
metadataLocalProperties = ApplicationContextAwareUtils.getApplicationContext().getBean(MetadataLocalProperties.class); metadataLocalProperties = ApplicationContextAwareUtils.getApplicationContext()
.getBean(MetadataLocalProperties.class);
} }
if (staticMetadataManager == null) { if (staticMetadataManager == null) {
staticMetadataManager = ApplicationContextAwareUtils.getApplicationContext().getBean(StaticMetadataManager.class); staticMetadataManager = ApplicationContextAwareUtils.getApplicationContext()
.getBean(StaticMetadataManager.class);
}
MetadataContainer metadataContainer = metadataManager.getMetadataContainer(MetadataType.CUSTOM, false);
Map<String, String> mergedStaticTransitiveMetadata = staticMetadataManager.getMergedStaticTransitiveMetadata();
for (Map.Entry<String, String> entry : mergedStaticTransitiveMetadata.entrySet()) {
metadataContainer.putMetadataStringValue(entry.getKey(), entry.getValue(), TransitiveType.PASS_THROUGH);
}
Map<String, String> mergedStaticDisposableMetadata = staticMetadataManager.getMergedStaticDisposableMetadata();
for (Map.Entry<String, String> entry : mergedStaticDisposableMetadata.entrySet()) {
metadataContainer.putMetadataStringValue(entry.getKey(), entry.getValue(), TransitiveType.DISPOSABLE);
} }
// init static transitive metadata
MetadataContext metadataContext = new MetadataContext();
metadataContext.setTransitiveMetadata(staticMetadataManager.getMergedStaticTransitiveMetadata());
metadataContext.setDisposableMetadata(staticMetadataManager.getMergedStaticDisposableMetadata());
if (StringUtils.hasText(staticMetadataManager.getTransHeader())) { if (StringUtils.hasText(staticMetadataManager.getTransHeader())) {
metadataContext.setTransHeaders(staticMetadataManager.getTransHeader(), ""); String transHeader = staticMetadataManager.getTransHeader();
metadataContainer.putMetadataMapValue(MetadataContext.FRAGMENT_RAW_TRANSHEADERS, transHeader, "", TransitiveType.NONE);
} }
return metadataManager;
METADATA_CONTEXT.set(metadataContext);
return METADATA_CONTEXT.get();
} }
/** /**
* Get disposable metadata value from thread local . * Get disposable metadata value from thread local .
*
* @param key metadata key . * @param key metadata key .
* @param upstream upstream disposable , otherwise will return local static disposable metadata . * @param upstream upstream disposable , otherwise will return local static disposable metadata .
* @return target disposable metadata value . * @return target disposable metadata value .
@ -95,6 +99,7 @@ public final class MetadataContextHolder {
/** /**
* Get all disposable metadata value from thread local . * Get all disposable metadata value from thread local .
*
* @param upstream upstream disposable , otherwise will return local static disposable metadata . * @param upstream upstream disposable , otherwise will return local static disposable metadata .
* @return target disposable metadata value . * @return target disposable metadata value .
*/ */
@ -112,44 +117,40 @@ public final class MetadataContextHolder {
/** /**
* Set metadata context. * Set metadata context.
*
* @param metadataContext metadata context * @param metadataContext metadata context
*/ */
public static void set(MetadataContext metadataContext) { public static void set(MetadataContext metadataContext) {
METADATA_CONTEXT.set(metadataContext); com.tencent.polaris.metadata.core.manager.MetadataContextHolder.set(metadataContext);
} }
/** /**
* Save metadata map to thread local. * Save metadata map to thread local.
*
* @param dynamicTransitiveMetadata custom metadata collection * @param dynamicTransitiveMetadata custom metadata collection
* @param dynamicDisposableMetadata custom disposable metadata connection * @param dynamicDisposableMetadata custom disposable metadata connection
*/ */
public static void init(Map<String, String> dynamicTransitiveMetadata, Map<String, String> dynamicDisposableMetadata) { public static void init(Map<String, String> dynamicTransitiveMetadata, Map<String, String> dynamicDisposableMetadata) {
// Init ThreadLocal. com.tencent.polaris.metadata.core.manager.MetadataContextHolder.refresh(MetadataContextHolder::createMetadataManager, metadataManager -> {
MetadataContextHolder.remove(); MetadataContainer metadataContainerUpstream = metadataManager.getMetadataContainer(MetadataType.CUSTOM, false);
MetadataContext metadataContext = MetadataContextHolder.get();
// Save transitive metadata to ThreadLocal.
if (!CollectionUtils.isEmpty(dynamicTransitiveMetadata)) { if (!CollectionUtils.isEmpty(dynamicTransitiveMetadata)) {
Map<String, String> staticTransitiveMetadata = metadataContext.getTransitiveMetadata(); for (Map.Entry<String, String> entry : dynamicTransitiveMetadata.entrySet()) {
Map<String, String> mergedTransitiveMetadata = new HashMap<>(); metadataContainerUpstream.putMetadataStringValue(entry.getKey(), entry.getValue(), TransitiveType.PASS_THROUGH);
mergedTransitiveMetadata.putAll(staticTransitiveMetadata); }
mergedTransitiveMetadata.putAll(dynamicTransitiveMetadata);
metadataContext.setTransitiveMetadata(Collections.unmodifiableMap(mergedTransitiveMetadata));
} }
MetadataContainer metadataContainerDownstream = metadataManager.getMetadataContainer(MetadataType.CUSTOM, true);
if (!CollectionUtils.isEmpty(dynamicDisposableMetadata)) { if (!CollectionUtils.isEmpty(dynamicDisposableMetadata)) {
Map<String, String> mergedUpstreamDisposableMetadata = new HashMap<>(dynamicDisposableMetadata); for (Map.Entry<String, String> entry : dynamicDisposableMetadata.entrySet()) {
metadataContext.setUpstreamDisposableMetadata(Collections.unmodifiableMap(mergedUpstreamDisposableMetadata)); metadataContainerDownstream.putMetadataStringValue(entry.getKey(), entry.getValue(), TransitiveType.DISPOSABLE);
} }
}
Map<String, String> staticDisposableMetadata = metadataContext.getFragmentContext(FRAGMENT_DISPOSABLE); });
metadataContext.setDisposableMetadata(Collections.unmodifiableMap(staticDisposableMetadata));
MetadataContextHolder.set(metadataContext);
} }
/** /**
* Remove metadata context. * Remove metadata context.
*/ */
public static void remove() { public static void remove() {
METADATA_CONTEXT.remove(); com.tencent.polaris.metadata.core.manager.MetadataContextHolder.remove();
} }
} }

@ -73,7 +73,7 @@
<revision>1.14.0-Hoxton.SR12-RC1</revision> <revision>1.14.0-Hoxton.SR12-RC1</revision>
<!-- Dependencies --> <!-- Dependencies -->
<polaris.version>1.15.2</polaris.version> <polaris.version>1.15.3-SNAPSHOT</polaris.version>
<guava.version>32.0.1-jre</guava.version> <guava.version>32.0.1-jre</guava.version>
<logback.version>1.2.13</logback.version> <logback.version>1.2.13</logback.version>
<springfox.swagger2.version>3.0.0</springfox.swagger2.version> <springfox.swagger2.version>3.0.0</springfox.swagger2.version>

Loading…
Cancel
Save