Skip to content

feat: support gateway context, feign eager-load support default value. #1496

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions spring-cloud-starter-tencent-all/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@
<artifactId>spring-cloud-starter-tencent-trace-plugin</artifactId>
</dependency>

<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-gateway-plugin</artifactId>
</dependency>

<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-auth</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
import java.util.HashMap;
import java.util.Map;

import com.tencent.cloud.common.constant.ContextConstant;
import com.tencent.cloud.common.constant.MetadataConstant;
import com.tencent.cloud.common.constant.OrderConstant;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.common.util.MetadataContextUtils;
import com.tencent.cloud.common.util.UrlUtils;
import com.tencent.cloud.metadata.provider.ReactiveMetadataProvider;
import com.tencent.polaris.api.utils.StringUtils;
Expand Down Expand Up @@ -95,6 +97,11 @@ public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain web
MetadataConstant.HeaderName.METADATA_CONTEXT,
MetadataContextHolder.get());

String targetNamespace = serverWebExchange.getRequest().getHeaders().getFirst(MetadataConstant.HeaderName.NAMESPACE);
if (StringUtils.isNotBlank(targetNamespace)) {
MetadataContextUtils.putCallerApplicationMetadataStringValue(
MetadataContextHolder.get(), ContextConstant.POLARIS_TARGET_NAMESPACE, targetNamespace);
}
TransHeadersTransfer.transfer(serverHttpRequest);
return webFilterChain.filter(serverWebExchange)
.doFinally((type) -> MetadataContextHolder.remove());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext;
import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter;
import com.tencent.polaris.api.utils.StringUtils;
import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
import com.tencent.polaris.metadata.core.MetadataType;
import org.slf4j.Logger;
Expand Down Expand Up @@ -69,10 +70,10 @@ public void run(EnhancedPluginContext context) throws Throwable {
EnhancedRequestContext request = context.getRequest();
EnhancedResponseContext response = context.getResponse();

String governanceNamespace = MetadataContext.LOCAL_NAMESPACE;

String host = request.getServiceUrl() != null ? request.getServiceUrl().getHost() : request.getUrl().getHost();
String path = request.getServiceUrl() != null ? request.getServiceUrl().getPath() : request.getUrl().getPath();
String governanceNamespace = StringUtils.isNotEmpty(request.getGovernanceNamespace()) ? request.getGovernanceNamespace() : MetadataContext.LOCAL_NAMESPACE;

String httpMethod = request.getHttpMethod().name();

CircuitBreaker circuitBreaker = circuitBreakerFactory.create(governanceNamespace + "#" + host + "#" + path + "#http#" + httpMethod);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,13 +213,17 @@ void initTsfConfigGroups(CompositePropertySource compositePropertySource) {
String tsfNamespaceName = environment.getProperty("tsf_namespace_name");
String tsfGroupName = environment.getProperty("tsf_group_name");

if (StringUtils.isEmpty(tsfId) || StringUtils.isEmpty(tsfNamespaceName) || StringUtils.isEmpty(tsfGroupName)) {
if (StringUtils.isEmpty(tsfNamespaceName) || StringUtils.isEmpty(tsfGroupName)) {
return;
}
String namespace = polarisContextProperties.getNamespace();
List<String> tsfConfigGroups = Arrays.asList(
tsfId + "." + tsfGroupName + ".application_config_group",
tsfId + "." + tsfNamespaceName + ".global_config_group");
List<String> tsfConfigGroups = new ArrayList<>();
tsfConfigGroups.add((StringUtils.hasText(tsfId) ? tsfId + "." : "") + tsfGroupName + ".application_config_group");
tsfConfigGroups.add((StringUtils.hasText(tsfId) ? tsfId + "." : "") + tsfNamespaceName + ".global_config_group");

if (isGatewayEnabled()) {
tsfConfigGroups.add((StringUtils.hasText(tsfId) ? tsfId + "." : "") + tsfGroupName + ".gateway_config_group");
}
for (String tsfConfigGroup : tsfConfigGroups) {
PolarisPropertySource polarisPropertySource = loadGroupPolarisPropertySource(configFileService, namespace, tsfConfigGroup);
if (polarisPropertySource == null) {
Expand Down Expand Up @@ -328,4 +332,14 @@ else if (ConfigFileFormat.isYamlFile(fileName)) {
}
return configKVFile;
}

public static boolean isGatewayEnabled() {
try {
Class.forName("org.springframework.cloud.gateway.filter.GlobalFilter");
return true;
}
catch (ClassNotFoundException e) {
return false;
}
}
}
12 changes: 12 additions & 0 deletions spring-cloud-starter-tencent-polaris-discovery/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@
</dependency>
<!-- Polaris dependencies end -->

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

package com.tencent.cloud.polaris.discovery;

import com.tencent.cloud.common.constant.ContextConstant;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.util.MetadataContextUtils;
import com.tencent.cloud.polaris.PolarisDiscoveryProperties;
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
import com.tencent.polaris.api.core.ConsumerAPI;
Expand Down Expand Up @@ -49,7 +52,9 @@ public PolarisDiscoveryHandler(PolarisDiscoveryProperties polarisDiscoveryProper
* @return list of healthy instances
*/
public InstancesResponse getHealthyInstances(String service) {
String namespace = polarisDiscoveryProperties.getNamespace();
String namespace = MetadataContextUtils.getCallerApplicationMetadataStringValue(
MetadataContextHolder.get(), ContextConstant.POLARIS_TARGET_NAMESPACE, polarisDiscoveryProperties.getNamespace());

GetHealthyInstancesRequest getHealthyInstancesRequest = new GetHealthyInstancesRequest();
getHealthyInstancesRequest.setNamespace(namespace);
getHealthyInstancesRequest.setService(service);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import org.springframework.context.annotation.Configuration;

@Configuration
@ConditionalOnProperty(name = "spring.cloud.polaris.discovery.eager-load.enabled", havingValue = "true")
@ConditionalOnProperty(name = "spring.cloud.polaris.discovery.eager-load.enabled", havingValue = "true", matchIfMissing = true)
public class PolarisEagerLoadAutoConfiguration {

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@

package com.tencent.cloud.polaris.eager.instrument.feign;

import com.tencent.cloud.common.util.FeignUtil;
import java.lang.reflect.Field;
import java.lang.reflect.Proxy;

import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClient;
import com.tencent.cloud.polaris.discovery.reactive.PolarisReactiveDiscoveryClient;
import com.tencent.polaris.api.utils.StringUtils;
import feign.Target;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.ApplicationContext;
import org.springframework.context.SmartLifecycle;

Expand All @@ -47,36 +51,59 @@ public FeignEagerLoadSmartLifecycle(ApplicationContext applicationContext, Polar
@Override
public void start() {
LOG.info("feign eager-load start");
for (String name : applicationContext.getBeanDefinitionNames()) {
for (Object bean : applicationContext.getBeansWithAnnotation(FeignClient.class).values()) {
try {
if (name.contains(FeignUtil.FEIGN_CLIENT_SPECIF) && !name.startsWith(FeignUtil.FEIGN_CLIENT_DEFAULT)) {
String feignName = FeignUtil.analysisFeignName(name, applicationContext);
if (StringUtils.isNotBlank(feignName)) {
LOG.info("[{}] eager-load start", feignName);
if (polarisDiscoveryClient != null) {
polarisDiscoveryClient.getInstances(feignName);
}
else if (polarisReactiveDiscoveryClient != null) {
polarisReactiveDiscoveryClient.getInstances(feignName).subscribe();
}
else {
LOG.warn("[{}] no discovery client found.", feignName);
if (Proxy.isProxyClass(bean.getClass())) {
Target.HardCodedTarget<?> hardCodedTarget = getHardCodedTarget(bean);
if (hardCodedTarget != null) {
FeignClient feignClient = hardCodedTarget.type().getAnnotation(FeignClient.class);
// if feignClient contains url, it doesn't need to eager load.
if (StringUtils.isEmpty(feignClient.url())) {
// support variables and default values.
String feignName = hardCodedTarget.name();
LOG.info("[{}] eager-load start", feignName);
if (polarisDiscoveryClient != null) {
polarisDiscoveryClient.getInstances(feignName);
}
else if (polarisReactiveDiscoveryClient != null) {
polarisReactiveDiscoveryClient.getInstances(feignName).subscribe();
}
else {
LOG.warn("[{}] no discovery client found.", feignName);
}
LOG.info("[{}] eager-load end", feignName);
}
LOG.info("[{}] eager-load end", feignName);
}
else {
LOG.warn("feign name is blank.");
}
}
}
catch (Exception e) {
LOG.error("[{}] eager-load failed.", name, e);
LOG.debug("[{}] eager-load failed.", bean, e);
}
}
LOG.info("feign eager-load end");

}

public static Target.HardCodedTarget<?> getHardCodedTarget(Object proxy) {
try {
Object invocationHandler = Proxy.getInvocationHandler(proxy);

for (Field field : invocationHandler.getClass().getDeclaredFields()) {
field.setAccessible(true);
Object fieldValue = field.get(invocationHandler);
if (fieldValue instanceof Target.HardCodedTarget) {
return (Target.HardCodedTarget<?>) fieldValue;
}
}
}
catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("proxy:{}, getTarget failed.", proxy, e);
}
}
return null;
}

@Override
public void stop() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@
import java.util.function.Function;
import java.util.stream.Collectors;

import com.tencent.cloud.common.constant.ContextConstant;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.util.MetadataContextUtils;
import com.tencent.cloud.rpc.enhancement.transformer.InstanceTransformer;
import com.tencent.polaris.api.pojo.DefaultServiceInstances;
import com.tencent.polaris.api.pojo.Instance;
Expand Down Expand Up @@ -72,7 +75,10 @@ public static ServiceInstances transferServersToServiceInstances(Flux<List<Servi
serviceMetadata = instanceList.get(0).getServiceMetadata();
}

ServiceKey serviceKey = new ServiceKey(MetadataContext.LOCAL_NAMESPACE, serviceName);
String namespace = MetadataContextUtils.getCallerApplicationMetadataStringValue(
MetadataContextHolder.get(), ContextConstant.POLARIS_TARGET_NAMESPACE, MetadataContext.LOCAL_NAMESPACE);

ServiceKey serviceKey = new ServiceKey(namespace, serviceName);

return new DefaultServiceInstances(serviceKey, instanceList, serviceMetadata);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ public final class ContextConstant {
* Default registry heartbeat time interval: 5 (s).
*/
public static final Integer DEFAULT_REGISTRY_HEARTBEAT_TIME_INTERVAL = 5;
/**
* Name of polaris target namespace.
*/
public static final String POLARIS_TARGET_NAMESPACE = "POLARIS_TARGET_NAMESPACE";

private ContextConstant() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ public static class HeaderName {
* Metadata context.
*/
public static final String METADATA_CONTEXT = "SCT-METADATA-CONTEXT";
/**
* Namespace context.
*/
public static final String NAMESPACE = "SCT-NAMESPACE";
}

public static class DefaultMetadata {
Expand Down

This file was deleted.

Loading
Loading