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

pull/1250/head
andrew shan 10 months 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>
<artifactId>polaris-model</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-metadata</artifactId>
</dependency>
<!-- Polaris dependencies end -->
<dependency>

@ -21,22 +21,25 @@ package com.tencent.cloud.common.metadata;
import java.util.Collections;
import java.util.HashMap;
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.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.LoggerFactory;
import org.springframework.util.StringUtils;
/**
* Metadata Context.
*
* @author Haotian Zhang
*/
public class MetadataContext {
public class MetadataContext extends com.tencent.polaris.metadata.core.manager.MetadataContext {
/**
* transitive context.
@ -63,6 +66,11 @@ public class MetadataContext {
*/
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);
/**
* Namespace of local instance.
@ -108,22 +116,70 @@ public class MetadataContext {
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() {
this.fragmentContexts = new ConcurrentHashMap<>();
this.loadbalancerMetadata = new ConcurrentHashMap<>();
private Map<String, String> getMapMetadataAsMap(MetadataType metadataType, String mapKey, TransitiveType transitiveType, boolean downstream) {
MetadataContainer metadataContainer = getMetadataContainer(metadataType, downstream);
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() {
return this.getFragmentContext(MetadataContext.FRAGMENT_DISPOSABLE);
return getFragmentContext(FRAGMENT_DISPOSABLE);
}
public Map<String, String> getTransitiveMetadata() {
return this.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE);
return getFragmentContext(FRAGMENT_TRANSITIVE);
}
public Map<String, String> getCustomMetadata() {
@ -140,51 +196,76 @@ public class MetadataContext {
}
public Map<String, String> getTransHeaders() {
return this.getFragmentContext(MetadataContext.FRAGMENT_RAW_TRANSHEADERS);
return this.getFragmentContext(FRAGMENT_RAW_TRANSHEADERS);
}
public Map<String, String> getTransHeadersKV() {
return this.getFragmentContext(MetadataContext.FRAGMENT_RAW_TRANSHEADERS_KV);
return getFragmentContext(FRAGMENT_RAW_TRANSHEADERS_KV);
}
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) {
this.putFragmentContext(FRAGMENT_TRANSITIVE, Collections.unmodifiableMap(transitiveMetadata));
putFragmentContext(FRAGMENT_TRANSITIVE, Collections.unmodifiableMap(transitiveMetadata));
}
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) {
this.putFragmentContext(FRAGMENT_UPSTREAM_DISPOSABLE, Collections.unmodifiableMap(upstreamDisposableMetadata));
putFragmentContext(FRAGMENT_UPSTREAM_DISPOSABLE, Collections.unmodifiableMap(upstreamDisposableMetadata));
}
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) {
this.putContext(FRAGMENT_RAW_TRANSHEADERS, key, value);
}
public void setLoadbalancer(String key, Object value) {
this.loadbalancerMetadata.put(key, value);
putContext(FRAGMENT_RAW_TRANSHEADERS, key, value);
}
public Map<String, String> getFragmentContext(String fragment) {
Map<String, String> fragmentContext = fragmentContexts.get(fragment);
if (fragmentContext == null) {
return Collections.emptyMap();
switch (fragment) {
case FRAGMENT_TRANSITIVE:
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) {
Map<String, String> fragmentContext = fragmentContexts.get(fragment);
Map<String, String> fragmentContext = getFragmentContext(fragment);
if (fragmentContext == null) {
return null;
}
@ -192,22 +273,32 @@ public class MetadataContext {
}
public void putContext(String fragment, String key, String value) {
Map<String, String> fragmentContext = fragmentContexts.get(fragment);
if (fragmentContext == null) {
fragmentContext = new ConcurrentHashMap<>();
fragmentContexts.put(fragment, fragmentContext);
}
fragmentContext.put(key, value);
Map<String, String> values = new HashMap<>();
values.put(key, value);
putFragmentContext(fragment, values);
}
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.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.StringUtils;
@ -38,8 +41,6 @@ import static com.tencent.cloud.common.metadata.MetadataContext.FRAGMENT_UPSTREA
*/
public final class MetadataContextHolder {
private static final ThreadLocal<MetadataContext> METADATA_CONTEXT = new InheritableThreadLocal<>();
private static MetadataLocalProperties metadataLocalProperties;
private static StaticMetadataManager staticMetadataManager;
@ -47,39 +48,42 @@ public final class MetadataContextHolder {
private MetadataContextHolder() {
}
/**
* Get metadata context. Create if not existing.
* @return METADATA_CONTEXT
*/
public static MetadataContext get() {
if (METADATA_CONTEXT.get() != null) {
return METADATA_CONTEXT.get();
}
return (MetadataContext) com.tencent.polaris.metadata.core.manager.MetadataContextHolder.getOrCreate(
MetadataContextHolder::createMetadataManager);
}
private static MetadataContext createMetadataManager() {
MetadataContext metadataManager = new MetadataContext();
if (metadataLocalProperties == null) {
metadataLocalProperties = ApplicationContextAwareUtils.getApplicationContext().getBean(MetadataLocalProperties.class);
metadataLocalProperties = ApplicationContextAwareUtils.getApplicationContext()
.getBean(MetadataLocalProperties.class);
}
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())) {
metadataContext.setTransHeaders(staticMetadataManager.getTransHeader(), "");
String transHeader = staticMetadataManager.getTransHeader();
metadataContainer.putMetadataMapValue(MetadataContext.FRAGMENT_RAW_TRANSHEADERS, transHeader, "", TransitiveType.NONE);
}
METADATA_CONTEXT.set(metadataContext);
return METADATA_CONTEXT.get();
return metadataManager;
}
/**
* 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 .
* @return target disposable metadata value .
*/
@ -95,6 +99,7 @@ public final class MetadataContextHolder {
/**
* Get all disposable metadata value from thread local .
*
* @param upstream upstream disposable , otherwise will return local static disposable metadata .
* @return target disposable metadata value .
*/
@ -112,44 +117,40 @@ public final class MetadataContextHolder {
/**
* Set metadata context.
*
* @param metadataContext metadata context
*/
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.
*
* @param dynamicTransitiveMetadata custom metadata collection
* @param dynamicDisposableMetadata custom disposable metadata connection
*/
public static void init(Map<String, String> dynamicTransitiveMetadata, Map<String, String> dynamicDisposableMetadata) {
// Init ThreadLocal.
MetadataContextHolder.remove();
MetadataContext metadataContext = MetadataContextHolder.get();
// Save transitive metadata to ThreadLocal.
if (!CollectionUtils.isEmpty(dynamicTransitiveMetadata)) {
Map<String, String> staticTransitiveMetadata = metadataContext.getTransitiveMetadata();
Map<String, String> mergedTransitiveMetadata = new HashMap<>();
mergedTransitiveMetadata.putAll(staticTransitiveMetadata);
mergedTransitiveMetadata.putAll(dynamicTransitiveMetadata);
metadataContext.setTransitiveMetadata(Collections.unmodifiableMap(mergedTransitiveMetadata));
}
if (!CollectionUtils.isEmpty(dynamicDisposableMetadata)) {
Map<String, String> mergedUpstreamDisposableMetadata = new HashMap<>(dynamicDisposableMetadata);
metadataContext.setUpstreamDisposableMetadata(Collections.unmodifiableMap(mergedUpstreamDisposableMetadata));
}
Map<String, String> staticDisposableMetadata = metadataContext.getFragmentContext(FRAGMENT_DISPOSABLE);
metadataContext.setDisposableMetadata(Collections.unmodifiableMap(staticDisposableMetadata));
MetadataContextHolder.set(metadataContext);
com.tencent.polaris.metadata.core.manager.MetadataContextHolder.refresh(MetadataContextHolder::createMetadataManager, metadataManager -> {
MetadataContainer metadataContainerUpstream = metadataManager.getMetadataContainer(MetadataType.CUSTOM, false);
if (!CollectionUtils.isEmpty(dynamicTransitiveMetadata)) {
for (Map.Entry<String, String> entry : dynamicTransitiveMetadata.entrySet()) {
metadataContainerUpstream.putMetadataStringValue(entry.getKey(), entry.getValue(), TransitiveType.PASS_THROUGH);
}
}
MetadataContainer metadataContainerDownstream = metadataManager.getMetadataContainer(MetadataType.CUSTOM, true);
if (!CollectionUtils.isEmpty(dynamicDisposableMetadata)) {
for (Map.Entry<String, String> entry : dynamicDisposableMetadata.entrySet()) {
metadataContainerDownstream.putMetadataStringValue(entry.getKey(), entry.getValue(), TransitiveType.DISPOSABLE);
}
}
});
}
/**
* Remove metadata context.
*/
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>
<!-- Dependencies -->
<polaris.version>1.15.2</polaris.version>
<polaris.version>1.15.3-SNAPSHOT</polaris.version>
<guava.version>32.0.1-jre</guava.version>
<logback.version>1.2.13</logback.version>
<springfox.swagger2.version>3.0.0</springfox.swagger2.version>

Loading…
Cancel
Save