feat:use polaris-all for shading third-party dependencies. (#1526)

pull/1527/head
Haotian Zhang 5 months ago committed by GitHub
parent b383bdd28e
commit c692707a8d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -5,3 +5,4 @@
- [feat:support polaris event.](https://github.com/Tencent/spring-cloud-tencent/pull/1523)
- [feat:support circuit breaker metrics reporting.](https://github.com/Tencent/spring-cloud-tencent/pull/1524)
- [feat: support gateway context, feign eager-load support default value.](https://github.com/Tencent/spring-cloud-tencent/pull/1525)
- [feat:use polaris-all for shading third-party dependencies.](https://github.com/Tencent/spring-cloud-tencent/pull/1526)

@ -104,6 +104,8 @@
<!-- Maven Plugin Versions -->
<jacoco.version>0.8.12</jacoco.version>
<flatten-maven-plugin.version>1.3.0</flatten-maven-plugin.version>
<maven-shade-plugin.version>3.5.1</maven-shade-plugin.version>
<maven-clean-plugin.version>3.4.0</maven-clean-plugin.version>
<!-- Checkstyle -->
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError>
@ -152,6 +154,38 @@
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>uk.org.webcompere</groupId>
<artifactId>system-stubs-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
@ -165,6 +199,11 @@
<artifactId>maven-shade-plugin</artifactId>
<version>${maven-shade-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>${maven-clean-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
@ -172,6 +211,20 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
<filesets>
<fileset>
<directory>${project.basedir}</directory>
<includes>
<include>dependency-reduced-pom.xml</include>
</includes>
</fileset>
</filesets>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>

@ -68,83 +68,6 @@
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-fault-tolerance</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<id>sct-all-shade</id>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createSourcesJar>true</createSourcesJar>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.MF</exclude>
<exclude>META-INF/NOTICE</exclude>
<exclude>META-INF/DEPENDENCIES</exclude>
<exclude>META-INF/LICENSE</exclude>
<exclude>META-INF/NOTICE.txt</exclude>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/io.netty.versions.properties</exclude>
<exclude>module-info.java</exclude>
<exclude>module-info.class</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/spring/org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration.imports
</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -19,7 +19,6 @@
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-rpc-enhancement</artifactId>
</dependency>
<!-- Spring Cloud Tencent dependencies end -->
<dependency>
@ -40,35 +39,11 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-test-mock-discovery</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-test-common</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -23,11 +23,11 @@ import java.util.List;
import java.util.Map;
import com.tencent.cloud.common.constant.MetadataConstant;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.util.CollectionUtils;
import org.springframework.web.server.ServerWebExchange;
/**

@ -22,7 +22,6 @@ import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.util.JacksonUtils;
@ -35,6 +34,7 @@ import com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant;
import com.tencent.polaris.metadata.core.MessageMetadataContainer;
import com.tencent.polaris.metadata.core.MetadataType;
import feign.Request;
import shade.polaris.com.google.common.collect.ImmutableMap;
import org.springframework.util.CollectionUtils;

@ -19,7 +19,6 @@ package com.tencent.cloud.metadata.core;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.util.JacksonUtils;
@ -30,6 +29,7 @@ import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
import com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant;
import com.tencent.polaris.metadata.core.MessageMetadataContainer;
import com.tencent.polaris.metadata.core.MetadataType;
import shade.polaris.com.google.common.collect.ImmutableMap;
import org.springframework.http.HttpRequest;
import org.springframework.util.CollectionUtils;

@ -19,7 +19,6 @@ package com.tencent.cloud.metadata.core;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import com.tencent.cloud.common.constant.MetadataConstant;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
@ -31,6 +30,7 @@ import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
import com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant;
import com.tencent.polaris.metadata.core.MessageMetadataContainer;
import com.tencent.polaris.metadata.core.MetadataType;
import shade.polaris.com.google.common.collect.ImmutableMap;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.CollectionUtils;

@ -19,7 +19,6 @@ package com.tencent.cloud.metadata.core;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.util.JacksonUtils;
@ -30,6 +29,7 @@ import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
import com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant;
import com.tencent.polaris.metadata.core.MessageMetadataContainer;
import com.tencent.polaris.metadata.core.MetadataType;
import shade.polaris.com.google.common.collect.ImmutableMap;
import org.springframework.util.CollectionUtils;
import org.springframework.web.reactive.function.client.ClientRequest;

@ -14,47 +14,12 @@
<dependencies>
<!-- Spring Cloud Tencent dependencies start -->
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-rpc-enhancement</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-metadata-transfer</artifactId>
</dependency>
<!-- Spring Cloud Tencent dependencies end -->
<!-- Polaris dependencies start -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-auth-factory</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>auth-block-allow-list</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-test-common</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-test-mock-discovery</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Polaris dependencies end -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -67,12 +32,6 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
@ -84,23 +43,5 @@
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -14,6 +14,12 @@
<dependencies>
<!-- Spring Cloud Tencent dependencies start -->
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-rpc-enhancement</artifactId>
</dependency>
<!-- Spring Cloud Tencent dependencies end -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -38,68 +44,6 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-rpc-enhancement</artifactId>
</dependency>
<!-- Spring Cloud Tencent dependencies end -->
<!-- Polaris dependencies start -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-circuitbreaker-factory</artifactId>
<exclusions>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-rule</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-nearby</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-namespace</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-metadata</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-canary</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-set</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-isolated</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-healthy</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>healthchecker-http</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>healthchecker-udp</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>healthchecker-tcp</artifactId>
</dependency>
<!-- Polaris dependencies end -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
@ -111,35 +55,5 @@
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-test-common</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-test-mock-discovery</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -22,8 +22,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.context.ServiceRuleManager;
@ -31,6 +29,8 @@ import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import shade.polaris.com.google.protobuf.InvalidProtocolBufferException;
import shade.polaris.com.google.protobuf.util.JsonFormat;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;

@ -27,7 +27,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import com.google.protobuf.util.JsonFormat;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerProperties;
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
@ -49,6 +48,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import shade.polaris.com.google.protobuf.util.JsonFormat;
import org.springframework.cloud.client.circuitbreaker.CircuitBreaker;

@ -19,7 +19,6 @@ package com.tencent.cloud.polaris.circuitbreaker.endpoint;
import java.util.Map;
import com.google.protobuf.StringValue;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.polaris.context.ServiceRuleManager;
import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto;
@ -28,6 +27,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import shade.polaris.com.google.protobuf.StringValue;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;

@ -27,64 +27,10 @@
</dependency>
<!-- Spring Cloud Tencent dependencies end -->
<!-- Polaris dependencies start -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-configuration-factory</artifactId>
<exclusions>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-rule</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-nearby</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-namespace</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-metadata</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-canary</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-set</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-isolated</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-healthy</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Polaris dependencies end -->
<!-- Spring cloud dependencies start -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-security-crypto</artifactId>
<groupId>org.springframework.security</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring cloud dependencies start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
@ -98,23 +44,5 @@
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -28,10 +28,10 @@ import com.tencent.cloud.polaris.config.config.PolarisCryptoConfigProperties;
import com.tencent.cloud.polaris.context.PolarisConfigurationConfigModifier;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import com.tencent.polaris.factory.config.ConfigurationImpl;
import com.tencent.polaris.factory.config.configuration.ConfigFilterConfigImpl;
import com.tencent.polaris.factory.config.configuration.ConnectorConfigImpl;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -139,8 +139,15 @@ public class ConfigurationModifier implements PolarisConfigurationConfigModifier
List<String> configAddresses = new ArrayList<>(polarisAddresses.size());
for (String address : polarisAddresses) {
String ip = StringUtils.substringBeforeLast(address, ":");
configAddresses.add(ip + ":" + polarisConfigProperties.getPort());
if (StringUtils.isNotBlank(address)) {
int pos = address.lastIndexOf(":");
if (pos != -1) {
configAddresses.add(address.substring(0, pos) + ":" + polarisConfigProperties.getPort());
}
else {
configAddresses.add(address);
}
}
}
return configAddresses;

@ -29,12 +29,13 @@ import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
import com.tencent.cloud.polaris.config.enums.ConfigFileFormat;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.polaris.api.utils.ClassUtils;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import com.tencent.polaris.configuration.api.core.ConfigFileMetadata;
import com.tencent.polaris.configuration.api.core.ConfigFileService;
import com.tencent.polaris.configuration.api.core.ConfigKVFile;
import com.tencent.polaris.configuration.client.internal.CompositeConfigFile;
import com.tencent.polaris.configuration.client.internal.DefaultConfigFileMetadata;
import org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -43,8 +44,6 @@ import org.springframework.core.annotation.Order;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
* Spring cloud reserved core configuration loading SPI.
@ -59,19 +58,14 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
private static final Logger LOGGER = LoggerFactory.getLogger(PolarisConfigFileLocator.class);
private static final String POLARIS_CONFIG_PROPERTY_SOURCE_NAME = "polaris-config";
private volatile static CompositePropertySource compositePropertySourceCache = null;
private final PolarisConfigProperties polarisConfigProperties;
private final PolarisContextProperties polarisContextProperties;
private final ConfigFileService configFileService;
private final Environment environment;
// this class provides customized logic for some customers to configure special business group files
private final PolarisConfigCustomExtensionLayer polarisConfigCustomExtensionLayer = PolarisServiceLoaderUtil.getPolarisConfigCustomExtensionLayer();
private volatile static CompositePropertySource compositePropertySourceCache = null;
public PolarisConfigFileLocator(PolarisConfigProperties polarisConfigProperties,
PolarisContextProperties polarisContextProperties, ConfigFileService configFileService, Environment environment) {
this.polarisConfigProperties = polarisConfigProperties;
@ -80,6 +74,65 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
this.environment = environment;
}
public static PolarisPropertySource loadPolarisPropertySource(ConfigFileService configFileService, String namespace, String group, String fileName) {
ConfigKVFile configKVFile = loadConfigKVFile(configFileService, namespace, group, fileName);
Map<String, Object> map = new ConcurrentHashMap<>();
for (String key : configKVFile.getPropertyNames()) {
map.put(key, configKVFile.getProperty(key, null));
}
return new PolarisPropertySource(namespace, group, fileName, configKVFile, map);
}
public static PolarisPropertySource loadGroupPolarisPropertySource(ConfigFileService configFileService, String namespace, String group) {
List<ConfigKVFile> configKVFiles = new ArrayList<>();
com.tencent.polaris.configuration.api.core.ConfigFileGroup remoteGroup = configFileService.getConfigFileGroup(namespace, group);
if (remoteGroup == null) {
return null;
}
for (ConfigFileMetadata configFile : remoteGroup.getConfigFileMetadataList()) {
String fileName = configFile.getFileName();
ConfigKVFile configKVFile = loadConfigKVFile(configFileService, namespace, group, fileName);
configKVFiles.add(configKVFile);
}
CompositeConfigFile compositeConfigFile = new CompositeConfigFile(configKVFiles);
Map<String, Object> map = new ConcurrentHashMap<>();
for (String key : compositeConfigFile.getPropertyNames()) {
String value = compositeConfigFile.getProperty(key, null);
map.put(key, value);
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("namespace='" + namespace + '\''
+ ", group='" + group + '\'' + ", fileName='" + compositeConfigFile + '\''
+ ", map='" + map + '\'');
}
return new PolarisPropertySource(namespace, group, "", compositeConfigFile, map);
}
public static ConfigKVFile loadConfigKVFile(ConfigFileService configFileService, String namespace, String group, String fileName) {
ConfigKVFile configKVFile;
// unknown extension is resolved as properties file
if (ConfigFileFormat.isPropertyFile(fileName) || ConfigFileFormat.isUnknownFile(fileName)) {
configKVFile = configFileService.getConfigPropertiesFile(namespace, group, fileName);
}
else if (ConfigFileFormat.isYamlFile(fileName)) {
configKVFile = configFileService.getConfigYamlFile(namespace, group, fileName);
}
else {
LOGGER.warn("[SCT Config] Unsupported config file. namespace = {}, group = {}, fileName = {}", namespace, group, fileName);
throw new IllegalStateException("Only configuration files in the format of properties / yaml / yaml" + " can be injected into the spring context");
}
return configKVFile;
}
/**
* order: spring boot default config files > custom config files > tsf default config group.
* @param environment The current Environment.
@ -102,7 +155,7 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
initInternalConfigFiles(compositePropertySource);
// load custom config files
List<ConfigFileGroup> configFileGroups = polarisConfigProperties.getGroups();
if (!CollectionUtils.isEmpty(configFileGroups)) {
if (CollectionUtils.isNotEmpty(configFileGroups)) {
initCustomPolarisConfigFiles(compositePropertySource, configFileGroups);
}
// load tsf default config group
@ -155,7 +208,7 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
private List<ConfigFileMetadata> getInternalConfigFiles() {
String namespace = polarisContextProperties.getNamespace();
String serviceName = polarisContextProperties.getService();
if (!StringUtils.hasText(serviceName)) {
if (StringUtils.isBlank(serviceName)) {
serviceName = environment.getProperty("spring.application.name");
}
@ -165,10 +218,10 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
String[] activeProfiles = environment.getActiveProfiles();
String[] defaultProfiles = environment.getDefaultProfiles();
List<String> profileList = new ArrayList<>();
if (ArrayUtils.isNotEmpty(activeProfiles)) {
if (CollectionUtils.isNotEmpty(activeProfiles)) {
profileList.addAll(Arrays.asList(activeProfiles));
}
else if (ArrayUtils.isNotEmpty(defaultProfiles)) {
else if (CollectionUtils.isNotEmpty(defaultProfiles)) {
profileList.addAll(Arrays.asList(defaultProfiles));
}
// build application config files
@ -181,7 +234,7 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
private void buildInternalApplicationConfigFiles(List<ConfigFileMetadata> internalConfigFiles, String namespace, String serviceName, List<String> profileList) {
for (String profile : profileList) {
if (!StringUtils.hasText(profile)) {
if (StringUtils.isBlank(profile)) {
continue;
}
internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "application-" + profile + ".properties"));
@ -196,7 +249,7 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
private void buildInternalBootstrapConfigFiles(List<ConfigFileMetadata> internalConfigFiles, String namespace, String serviceName, List<String> profileList) {
for (String profile : profileList) {
if (!StringUtils.hasText(profile)) {
if (StringUtils.isBlank(profile)) {
continue;
}
internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "bootstrap-" + profile + ".properties"));
@ -219,11 +272,11 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
}
String namespace = polarisContextProperties.getNamespace();
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");
tsfConfigGroups.add((StringUtils.isNotBlank(tsfId) ? tsfId + "." : "") + tsfGroupName + ".application_config_group");
tsfConfigGroups.add((StringUtils.isNotBlank(tsfId) ? tsfId + "." : "") + tsfNamespaceName + ".global_config_group");
if (ClassUtils.isClassPresent("org.springframework.cloud.gateway.filter.GlobalFilter")) {
tsfConfigGroups.add((StringUtils.hasText(tsfId) ? tsfId + "." : "") + tsfGroupName + ".gateway_config_group");
tsfConfigGroups.add((StringUtils.isNotBlank(tsfId) ? tsfId + "." : "") + tsfGroupName + ".gateway_config_group");
}
for (String tsfConfigGroup : tsfConfigGroups) {
PolarisPropertySource polarisPropertySource = loadGroupPolarisPropertySource(configFileService, namespace, tsfConfigGroup);
@ -241,12 +294,12 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
for (ConfigFileGroup configFileGroup : configFileGroups) {
String groupNamespace = configFileGroup.getNamespace();
if (!StringUtils.hasText(groupNamespace)) {
if (StringUtils.isBlank(groupNamespace)) {
groupNamespace = namespace;
}
String group = configFileGroup.getName();
if (!StringUtils.hasText(group)) {
if (StringUtils.isBlank(group)) {
continue;
}
@ -274,63 +327,4 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
}
}
}
public static PolarisPropertySource loadPolarisPropertySource(ConfigFileService configFileService, String namespace, String group, String fileName) {
ConfigKVFile configKVFile = loadConfigKVFile(configFileService, namespace, group, fileName);
Map<String, Object> map = new ConcurrentHashMap<>();
for (String key : configKVFile.getPropertyNames()) {
map.put(key, configKVFile.getProperty(key, null));
}
return new PolarisPropertySource(namespace, group, fileName, configKVFile, map);
}
public static PolarisPropertySource loadGroupPolarisPropertySource(ConfigFileService configFileService, String namespace, String group) {
List<ConfigKVFile> configKVFiles = new ArrayList<>();
com.tencent.polaris.configuration.api.core.ConfigFileGroup remoteGroup = configFileService.getConfigFileGroup(namespace, group);
if (remoteGroup == null) {
return null;
}
for (ConfigFileMetadata configFile : remoteGroup.getConfigFileMetadataList()) {
String fileName = configFile.getFileName();
ConfigKVFile configKVFile = loadConfigKVFile(configFileService, namespace, group, fileName);
configKVFiles.add(configKVFile);
}
CompositeConfigFile compositeConfigFile = new CompositeConfigFile(configKVFiles);
Map<String, Object> map = new ConcurrentHashMap<>();
for (String key : compositeConfigFile.getPropertyNames()) {
String value = compositeConfigFile.getProperty(key, null);
map.put(key, value);
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("namespace='" + namespace + '\''
+ ", group='" + group + '\'' + ", fileName='" + compositeConfigFile + '\''
+ ", map='" + map + '\'');
}
return new PolarisPropertySource(namespace, group, "", compositeConfigFile, map);
}
public static ConfigKVFile loadConfigKVFile(ConfigFileService configFileService, String namespace, String group, String fileName) {
ConfigKVFile configKVFile;
// unknown extension is resolved as properties file
if (ConfigFileFormat.isPropertyFile(fileName) || ConfigFileFormat.isUnknownFile(fileName)) {
configKVFile = configFileService.getConfigPropertiesFile(namespace, group, fileName);
}
else if (ConfigFileFormat.isYamlFile(fileName)) {
configKVFile = configFileService.getConfigYamlFile(namespace, group, fileName);
}
else {
LOGGER.warn("[SCT Config] Unsupported config file. namespace = {}, group = {}, fileName = {}", namespace, group, fileName);
throw new IllegalStateException("Only configuration files in the format of properties / yaml / yaml" + " can be injected into the spring context");
}
return configKVFile;
}
}

@ -28,17 +28,16 @@ import com.tencent.cloud.polaris.config.config.ConfigFileGroup;
import com.tencent.cloud.polaris.config.configdata.PolarisConfigDataLoader;
import com.tencent.cloud.polaris.config.enums.ConfigFileFormat;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import com.tencent.polaris.configuration.api.core.ConfigFileMetadata;
import com.tencent.polaris.configuration.api.core.ConfigFileService;
import com.tencent.polaris.configuration.api.core.ConfigKVFile;
import com.tencent.polaris.configuration.client.internal.DefaultConfigFileMetadata;
import org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
* PolarisConfigFilePuller pull configFile from Polaris.
@ -113,11 +112,11 @@ public final class PolarisConfigFilePuller {
public void initCustomPolarisConfigFile(CompositePropertySource compositePropertySource,
ConfigFileGroup configFileGroup) {
String groupNamespace = configFileGroup.getNamespace();
if (!StringUtils.hasText(groupNamespace)) {
if (StringUtils.isBlank(groupNamespace)) {
groupNamespace = polarisContextProperties.getNamespace();
}
String group = configFileGroup.getName();
if (!StringUtils.hasText(group)) {
if (StringUtils.isBlank(group)) {
throw new IllegalArgumentException("polaris config group name cannot be empty.");
}
List<String> files = configFileGroup.getFiles();
@ -160,7 +159,7 @@ public final class PolarisConfigFilePuller {
private List<ConfigFileMetadata> getInternalConfigFiles(
String[] activeProfiles, String[] defaultProfiles, String serviceName) {
String namespace = polarisContextProperties.getNamespace();
if (StringUtils.hasText(polarisContextProperties.getService())) {
if (StringUtils.isNotBlank(polarisContextProperties.getService())) {
serviceName = polarisContextProperties.getService();
}
// priority: application-${profile} > application > boostrap-${profile} > boostrap
@ -170,10 +169,10 @@ public final class PolarisConfigFilePuller {
private List<ConfigFileMetadata> getInternalConfigFiles(
String[] activeProfiles, String[] defaultProfiles, String namespace, String serviceName) {
List<String> profileList = new ArrayList<>();
if (ArrayUtils.isNotEmpty(activeProfiles)) {
if (CollectionUtils.isNotEmpty(activeProfiles)) {
profileList.addAll(Arrays.asList(activeProfiles));
}
else if (ArrayUtils.isNotEmpty(defaultProfiles)) {
else if (CollectionUtils.isNotEmpty(defaultProfiles)) {
profileList.addAll(Arrays.asList(defaultProfiles));
}
@ -189,7 +188,7 @@ public final class PolarisConfigFilePuller {
private void buildInternalApplicationConfigFiles(
List<ConfigFileMetadata> internalConfigFiles, String namespace, String serviceName, List<String> profiles) {
for (String profile : profiles) {
if (!StringUtils.hasText(profile)) {
if (StringUtils.isBlank(profile)) {
continue;
}
internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "application-" + profile + ".properties"));
@ -205,7 +204,7 @@ public final class PolarisConfigFilePuller {
private void buildInternalBootstrapConfigFiles(
List<ConfigFileMetadata> internalConfigFiles, String namespace, String serviceName, List<String> profiles) {
for (String profile : profiles) {
if (!StringUtils.hasText(profile)) {
if (StringUtils.isBlank(profile)) {
continue;
}
internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "bootstrap-" + profile + ".properties"));

@ -26,7 +26,6 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import com.google.common.collect.Sets;
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
import com.tencent.cloud.polaris.config.logger.PolarisConfigLoggerContext;
import com.tencent.cloud.polaris.config.utils.PolarisPropertySourceUtils;
@ -39,6 +38,7 @@ import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
import com.tencent.polaris.configuration.client.internal.CompositeConfigFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import shade.polaris.com.google.common.collect.Sets;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
@ -55,16 +55,11 @@ import org.springframework.util.CollectionUtils;
public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationListener<ApplicationReadyEvent>, PolarisConfigPropertyRefresher {
private static final Logger LOGGER = LoggerFactory.getLogger(PolarisConfigPropertyAutoRefresher.class);
private static final Set<String> registeredPolarisPropertySets = Sets.newConcurrentHashSet();
private final PolarisConfigProperties polarisConfigProperties;
private final AtomicBoolean registered = new AtomicBoolean(false);
// this class provides customized logic for some customers to configure special business group files
private final PolarisConfigCustomExtensionLayer polarisConfigCustomExtensionLayer = PolarisServiceLoaderUtil.getPolarisConfigCustomExtensionLayer();
private static final Set<String> registeredPolarisPropertySets = Sets.newConcurrentHashSet();
private final ConfigFileService configFileService;
public PolarisConfigPropertyAutoRefresher(PolarisConfigProperties polarisConfigProperties,

@ -18,15 +18,16 @@
package com.tencent.cloud.polaris.config.annotation;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import com.tencent.cloud.polaris.config.listener.ConfigChangeEvent;
import com.tencent.cloud.polaris.config.listener.ConfigChangeListener;
import com.tencent.cloud.polaris.config.listener.SyncConfigChangeListener;
import shade.polaris.com.google.common.base.Preconditions;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
@ -104,11 +105,14 @@ public class PolarisConfigAnnotationProcessor implements BeanPostProcessor, Prio
}
};
Set<String> interestedKeys =
annotatedInterestedKeys.length > 0 ? Sets.newHashSet(annotatedInterestedKeys) : null;
Set<String> interestedKeyPrefixes =
annotatedInterestedKeyPrefixes.length > 0 ? Sets.newHashSet(annotatedInterestedKeyPrefixes)
: null;
Set<String> interestedKeys = new HashSet<>();
if (annotatedInterestedKeys.length > 0) {
Collections.addAll(interestedKeys, annotatedInterestedKeys);
}
Set<String> interestedKeyPrefixes = new HashSet<>();
if (annotatedInterestedKeyPrefixes.length > 0) {
Collections.addAll(interestedKeyPrefixes, annotatedInterestedKeyPrefixes);
}
addChangeListener(configChangeListener, interestedKeys, interestedKeyPrefixes);
}

@ -22,7 +22,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import com.google.common.collect.Maps;
import com.tencent.cloud.polaris.config.spring.event.ConfigChangeSpringEvent;
import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
import org.slf4j.Logger;
@ -96,7 +95,7 @@ public final class PolarisConfigChangeEventListener implements ApplicationListen
*/
@SuppressWarnings("unchecked")
private Map<String, Object> loadEnvironmentProperties(ConfigurableEnvironment environment) {
Map<String, Object> ret = Maps.newHashMap();
Map<String, Object> ret = new HashMap<>();
MutablePropertySources sources = environment.getPropertySources();
sources.iterator().forEachRemaining(propertySource -> {
// Don't read system env variable.

@ -17,26 +17,28 @@
package com.tencent.cloud.polaris.config.listener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeListener;
import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import shade.polaris.com.google.common.cache.Cache;
import shade.polaris.com.google.common.cache.CacheBuilder;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
@ -65,15 +67,15 @@ public final class PolarisConfigListenerContext {
/**
* All custom {@link ConfigChangeListener} instance defined in application .
*/
private static final List<ConfigChangeListener> listeners = Lists.newCopyOnWriteArrayList();
private static final List<ConfigChangeListener> listeners = new CopyOnWriteArrayList<>();
/**
* All custom interested keys defined in application .
*/
private static final Map<ConfigChangeListener, Set<String>> interestedKeys = Maps.newConcurrentMap();
private static final Map<ConfigChangeListener, Set<String>> interestedKeys = new ConcurrentHashMap<>();
/**
* All custom interested key prefixes defined in application .
*/
private static final Map<ConfigChangeListener, Set<String>> interestedKeyPrefixes = Maps.newConcurrentMap();
private static final Map<ConfigChangeListener, Set<String>> interestedKeyPrefixes = new ConcurrentHashMap<>();
/**
* Cache all latest configuration information for users in the application environment .
*/
@ -129,11 +131,11 @@ public final class PolarisConfigListenerContext {
* @return merged properties result map
*/
static Map<String, ConfigPropertyChangeInfo> merge(Map<String, Object> ret) {
Map<String, ConfigPropertyChangeInfo> changes = Maps.newHashMap();
Map<String, ConfigPropertyChangeInfo> changes = new HashMap<>();
if (!ret.isEmpty()) {
Map<String, Object> origin = Maps.newHashMap(properties.asMap());
Map<String, ConfigPropertyChangeInfo> deleted = Maps.newHashMap();
Map<String, Object> origin = new HashMap<>(properties.asMap());
Map<String, ConfigPropertyChangeInfo> deleted = new HashMap<>();
origin.keySet().parallelStream().forEach(key -> {
if (!ret.containsKey(key)) {
@ -175,8 +177,8 @@ public final class PolarisConfigListenerContext {
@Nullable Set<String> interestedKeys, @Nullable Set<String> interestedKeyPrefixes) {
if (!listeners.contains(listener)) {
listeners.add(listener);
PolarisConfigListenerContext.interestedKeys.put(listener, interestedKeys == null ? Sets.newHashSet() : interestedKeys);
PolarisConfigListenerContext.interestedKeyPrefixes.put(listener, interestedKeyPrefixes == null ? Sets.newHashSet() : interestedKeyPrefixes);
PolarisConfigListenerContext.interestedKeys.put(listener, CollectionUtils.isEmpty(interestedKeys) ? new HashSet<>() : interestedKeys);
PolarisConfigListenerContext.interestedKeyPrefixes.put(listener, CollectionUtils.isEmpty(interestedKeyPrefixes) ? new HashSet<>() : interestedKeyPrefixes);
}
}
@ -211,7 +213,7 @@ public final class PolarisConfigListenerContext {
* @return list of matched {@link ConfigChangeListener}
*/
private static List<ConfigChangeListener> findMatchedConfigChangeListeners(Set<String> changedKeys) {
final List<ConfigChangeListener> configChangeListeners = Lists.newArrayList();
final List<ConfigChangeListener> configChangeListeners = new ArrayList<>();
for (ConfigChangeListener listener : listeners) {
if (isConfigChangeListenerInterested(listener, changedKeys)) {
configChangeListeners.add(listener);
@ -262,7 +264,7 @@ public final class PolarisConfigListenerContext {
* @return set of all interested keys in listener
*/
private static Set<String> resolveInterestedChangedKeys(ConfigChangeListener listener, Set<String> changedKeys) {
Set<String> interestedChangedKeys = Sets.newHashSet();
Set<String> interestedChangedKeys = new HashSet<>();
if (interestedKeys.containsKey(listener)) {
Set<String> interestedKeys = PolarisConfigListenerContext.interestedKeys.get(listener);

@ -26,12 +26,8 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import com.google.common.base.CaseFormat;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
import com.tencent.cloud.polaris.config.spring.property.PlaceholderHelper;
import com.tencent.cloud.polaris.config.spring.property.SpringValue;
@ -40,6 +36,10 @@ import com.tencent.cloud.polaris.config.spring.property.SpringValueRegistry;
import com.tencent.polaris.api.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import shade.polaris.com.google.common.base.CaseFormat;
import shade.polaris.com.google.common.collect.LinkedListMultimap;
import shade.polaris.com.google.common.collect.Multimap;
import shade.polaris.com.google.common.collect.Sets;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
@ -73,7 +73,7 @@ public class SpringValueProcessor extends PolarisProcessor implements BeanDefini
private static final Set<BeanDefinitionRegistry> PROPERTY_VALUES_PROCESSED_BEAN_FACTORIES = Sets.newConcurrentHashSet();
private static final Map<BeanDefinitionRegistry, Multimap<String, SpringValueDefinition>> BEAN_DEFINITION_REGISTRY_MULTIMAP_CONCURRENT_MAP =
Maps.newConcurrentMap();
new ConcurrentHashMap<>();
private final PolarisConfigProperties polarisConfigProperties;
private final PlaceholderHelper placeholderHelper;
private final SpringValueRegistry springValueRegistry;
@ -90,6 +90,33 @@ public class SpringValueProcessor extends PolarisProcessor implements BeanDefini
beanName2SpringValueDefinitions = LinkedListMultimap.create();
}
/**
* whether the class is primitive or wrapper.
* @param clazz the class under analysis.
* @return true if the class is primitive or wrapper, otherwise false.
*/
private static boolean isPrimitiveOrWrapper(Class<?> clazz) {
return clazz.isPrimitive() ||
clazz == String.class ||
clazz == Boolean.class ||
clazz == Character.class ||
clazz == Byte.class ||
clazz == Short.class ||
clazz == Integer.class ||
clazz == Long.class ||
clazz == Float.class ||
clazz == Double.class;
}
/**
* whether the class is collection(array, collection, map).
* @param clazz the class under analysis.
* @return true if the class is collection(array, collection, map), otherwise false.
*/
private static boolean isCollection(Class<?> clazz) {
return clazz.isArray() || Collection.class.isAssignableFrom(clazz) || Map.class.isAssignableFrom(clazz);
}
@Override
public void postProcessBeanFactory(@NonNull ConfigurableListableBeanFactory beanFactory)
throws BeansException {
@ -108,7 +135,6 @@ public class SpringValueProcessor extends PolarisProcessor implements BeanDefini
return bean;
}
@Override
protected void processField(Object bean, String beanName, Field field, boolean isRefreshScope) {
// register @Value on field
@ -169,7 +195,8 @@ public class SpringValueProcessor extends PolarisProcessor implements BeanDefini
springValueRegistry.putRefreshScopeKeys(keys);
}
// method parameter class with @ConfigurationProperties
ConfigurationProperties configurationProperties = parameter.getType().getAnnotation(ConfigurationProperties.class);
ConfigurationProperties configurationProperties = parameter.getType()
.getAnnotation(ConfigurationProperties.class);
parseConfigurationPropertiesKeys(configurationProperties, parameter.getType());
}
@ -183,7 +210,8 @@ public class SpringValueProcessor extends PolarisProcessor implements BeanDefini
continue;
}
// field class with @ConfigurationProperties
ConfigurationProperties configurationProperties = field.getType().getAnnotation(ConfigurationProperties.class);
ConfigurationProperties configurationProperties = field.getType()
.getAnnotation(ConfigurationProperties.class);
parseConfigurationPropertiesKeys(configurationProperties, field.getType());
}
}
@ -241,33 +269,6 @@ public class SpringValueProcessor extends PolarisProcessor implements BeanDefini
}
}
/**
* whether the class is primitive or wrapper.
* @param clazz the class under analysis.
* @return true if the class is primitive or wrapper, otherwise false.
*/
private static boolean isPrimitiveOrWrapper(Class<?> clazz) {
return clazz.isPrimitive() ||
clazz == String.class ||
clazz == Boolean.class ||
clazz == Character.class ||
clazz == Byte.class ||
clazz == Short.class ||
clazz == Integer.class ||
clazz == Long.class ||
clazz == Float.class ||
clazz == Double.class;
}
/**
* whether the class is collection(array, collection, map).
* @param clazz the class under analysis.
* @return true if the class is collection(array, collection, map), otherwise false.
*/
private static boolean isCollection(Class<?> clazz) {
return clazz.isArray() || Collection.class.isAssignableFrom(clazz) || Map.class.isAssignableFrom(clazz);
}
@Override
public void setBeanFactory(@NonNull BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;

@ -17,17 +17,16 @@
package com.tencent.cloud.polaris.config.spring.property;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.tencent.polaris.api.utils.StringUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanExpressionContext;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.Scope;
import org.springframework.util.StringUtils;
/**
* Placeholder helper functions.
@ -89,7 +88,7 @@ public class PlaceholderHelper {
* </ul>
*/
public Set<String> extractPlaceholderKeys(String propertyString) {
Set<String> placeholderKeys = Sets.newHashSet();
Set<String> placeholderKeys = new HashSet<>();
if (!isPlaceholder(propertyString)) {
return placeholderKeys;
@ -128,7 +127,7 @@ public class PlaceholderHelper {
stack.push(placeholderCandidate.substring(0, separatorIndex));
String defaultValuePart =
normalizeToPlaceholder(placeholderCandidate.substring(separatorIndex + VALUE_SEPARATOR.length()));
if (!Strings.isNullOrEmpty(defaultValuePart)) {
if (StringUtils.isNotBlank(defaultValuePart)) {
stack.push(defaultValuePart);
}
}
@ -137,7 +136,7 @@ public class PlaceholderHelper {
// has remaining part, e.g. ${a}.${b}
if (endIndex + PLACEHOLDER_SUFFIX.length() < strVal.length() - 1) {
String remainingPart = normalizeToPlaceholder(strVal.substring(endIndex + PLACEHOLDER_SUFFIX.length()));
if (!Strings.isNullOrEmpty(remainingPart)) {
if (StringUtils.isNotBlank(remainingPart)) {
stack.push(remainingPart);
}
}
@ -147,7 +146,7 @@ public class PlaceholderHelper {
}
private boolean isPlaceholder(String propertyString) {
return !Strings.isNullOrEmpty(propertyString) &&
return StringUtils.isNotBlank(propertyString) &&
(isNormalizedPlaceholder(propertyString) || isExpressionWithPlaceholder(propertyString));
}

@ -21,21 +21,21 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import com.tencent.polaris.api.pojo.TrieNode;
import com.tencent.polaris.api.utils.TrieUtil;
import com.tencent.polaris.client.util.NamedThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import shade.polaris.com.google.common.collect.LinkedListMultimap;
import shade.polaris.com.google.common.collect.Multimap;
import shade.polaris.com.google.common.collect.Multimaps;
import shade.polaris.com.google.common.collect.Sets;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.DisposableBean;
@ -53,14 +53,12 @@ public class SpringValueRegistry implements DisposableBean {
private static final Logger logger = LoggerFactory.getLogger(SpringValueRegistry.class);
private static final long CLEAN_INTERVAL_IN_SECONDS = 5;
private final Map<BeanFactory, Multimap<String, SpringValue>> registry = Maps.newConcurrentMap();
private final Map<BeanFactory, Multimap<String, SpringValue>> registry = new ConcurrentHashMap<>();
private final AtomicBoolean initialized = new AtomicBoolean(false);
private final Object LOCK = new Object();
private ScheduledExecutorService executor;
private final TrieNode<String> refreshScopePrefixRoot = new TrieNode<>(TrieNode.ROOT_PATH);
private final Set<String> refreshScopeKeys = Sets.newConcurrentHashSet();
private ScheduledExecutorService executor;
public void register(BeanFactory beanFactory, String key, SpringValue springValue) {
if (!registry.containsKey(beanFactory)) {

@ -24,6 +24,7 @@ import com.tencent.tsf.consul.config.watch.TsfConsulConfigRefreshEventListener;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -51,6 +52,7 @@ public class PolarisAdaptorTsfConfigAutoConfiguration {
*/
@Bean
@ConditionalOnMissingBean
@ConditionalOnWebApplication
@ConditionalOnProperty(name = "tsf.config.instance.released-config.lookup.enabled", matchIfMissing = true)
public PolarisAdaptorTsfConfigController polarisAdaptorTsfConfigController() {
return new PolarisAdaptorTsfConfigController();

@ -18,13 +18,13 @@
package com.tencent.cloud.polaris.config.adapter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import com.tencent.cloud.polaris.config.config.ConfigFileGroup;
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
import com.tencent.cloud.polaris.config.enums.RefreshType;
@ -188,7 +188,10 @@ public class PolarisConfigFileLocatorTest {
configFileGroup.setName(customGroup);
String customFile1 = "file1.properties";
String customFile2 = "file2.properties";
configFileGroup.setFiles(Lists.newArrayList(customFile1, customFile2));
List<String> files = new ArrayList<>();
files.add(customFile1);
files.add(customFile2);
configFileGroup.setFiles(files);
customFiles.add(configFileGroup);
when(polarisConfigProperties.isEnabled()).thenReturn(true);

@ -22,7 +22,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import com.tencent.cloud.polaris.config.config.ConfigFileGroup;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.polaris.configuration.api.core.ConfigFileService;
@ -149,7 +148,10 @@ public class PolarisConfigFilePullerTest {
configFileGroup.setName(customGroup);
String customFile1 = "file1.properties";
String customFile2 = "file2.properties";
configFileGroup.setFiles(Lists.newArrayList(customFile1, customFile2));
List<String> files = new ArrayList<>();
files.add(customFile1);
files.add(customFile2);
configFileGroup.setFiles(files);
customFiles.add(configFileGroup);
// file1.properties

@ -22,7 +22,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import com.tencent.cloud.polaris.config.adapter.MockedConfigKVFile;
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
@ -109,7 +108,7 @@ public class PolarisConfigDataLoaderTest {
when(polarisConfigProperties.getGroups()).thenReturn(null);
when(polarisConfigProperties.isInternalEnabled()).thenReturn(true);
when(profiles.getActive()).thenReturn(Lists.newArrayList());
when(profiles.getActive()).thenReturn(new ArrayList<>());
PolarisConfigDataLoader polarisConfigDataLoader = new PolarisConfigDataLoader(new DeferredLogs());
if (INTERNAL_CONFIG_FILES_LOADED.get()) {
@ -244,7 +243,7 @@ public class PolarisConfigDataLoaderTest {
when(polarisConfigProperties.getGroups()).thenReturn(null);
when(polarisConfigProperties.isInternalEnabled()).thenReturn(true);
when(profiles.getActive()).thenReturn(Lists.newArrayList());
when(profiles.getActive()).thenReturn(new ArrayList<>());
// file1.properties
Map<String, Object> file1Map = new HashMap<>();
@ -260,7 +259,7 @@ public class PolarisConfigDataLoaderTest {
when(polarisContextProperties.getService()).thenReturn(testServiceName);
when(polarisConfigProperties.getGroups()).thenReturn(null);
when(profiles.getActive()).thenReturn(Lists.newArrayList());
when(profiles.getActive()).thenReturn(new ArrayList<>());
PolarisConfigDataLoader polarisConfigDataLoader = new PolarisConfigDataLoader(new DeferredLogs());

@ -17,10 +17,10 @@
package com.tencent.cloud.polaris.config.endpoint;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.google.common.collect.Lists;
import com.tencent.cloud.polaris.config.adapter.MockedConfigKVFile;
import com.tencent.cloud.polaris.config.adapter.PolarisPropertySource;
import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager;
@ -67,6 +67,6 @@ public class PolarisConfigEndpointTest {
PolarisConfigEndpoint endpoint = new PolarisConfigEndpoint(polarisConfigProperties);
Map<String, Object> info = endpoint.polarisConfig();
assertThat(polarisConfigProperties).isEqualTo(info.get("PolarisConfigProperties"));
assertThat(Lists.newArrayList(polarisPropertySource)).isEqualTo(info.get("PolarisPropertySource"));
assertThat(Collections.singletonList(polarisPropertySource)).isEqualTo(info.get("PolarisPropertySource"));
}
}

@ -18,10 +18,11 @@
package com.tencent.cloud.polaris.config.listener;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import com.google.common.collect.Sets;
import com.tencent.cloud.polaris.config.adapter.PolarisConfigFileLocator;
import com.tencent.cloud.polaris.config.annotation.PolarisConfigKVFileChangeListener;
import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
@ -83,8 +84,9 @@ public class ConfigChangeListenerTest {
//submit change event
System.setProperty("timeout", "2000");
EnvironmentChangeEvent event = new EnvironmentChangeEvent(applicationContext,
Sets.newHashSet("timeout"));
Set<String> ketSet = new HashSet<>();
ketSet.add("timeout");
EnvironmentChangeEvent event = new EnvironmentChangeEvent(applicationContext, ketSet);
applicationEventPublisher.publishEvent(event);

@ -38,17 +38,27 @@
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

@ -33,6 +33,7 @@ import com.tencent.polaris.api.core.ProviderAPI;
import com.tencent.polaris.api.plugin.server.InterfaceDescriptor;
import com.tencent.polaris.api.plugin.server.ReportServiceContractRequest;
import com.tencent.polaris.api.plugin.server.ReportServiceContractResponse;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
@ -49,7 +50,6 @@ import org.springdoc.webmvc.api.OpenApiWebMvcUtil;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.lang.NonNull;
import org.springframework.util.CollectionUtils;
/**
* Polaris contract reporter.

@ -33,29 +33,11 @@
<!-- Spring Cloud Tencent dependencies end -->
<!-- Polaris dependencies start -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-test-common</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>connector-nacos</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-test-mock-discovery</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Polaris dependencies end -->
<dependency>
@ -82,12 +64,6 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
@ -99,22 +75,5 @@
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -17,16 +17,13 @@
package com.tencent.cloud.polaris.discovery;
import com.tencent.cloud.polaris.PolarisDiscoveryProperties;
import com.tencent.cloud.polaris.discovery.reactive.PolarisReactiveDiscoveryClientConfiguration;
import com.tencent.cloud.polaris.discovery.refresh.PolarisRefreshConfiguration;
import com.tencent.cloud.polaris.extend.nacos.NacosContextProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.lang.Nullable;
/**
* Discovery Auto Configuration for Polaris.
@ -41,13 +38,7 @@ public class PolarisDiscoveryAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public PolarisServiceDiscovery polarisServiceDiscovery(
@Nullable NacosContextProperties nacosContextProperties,
PolarisDiscoveryProperties polarisDiscoveryProperties,
PolarisDiscoveryHandler polarisDiscoveryHandler) {
return new PolarisServiceDiscovery(
nacosContextProperties,
polarisDiscoveryProperties,
polarisDiscoveryHandler);
public PolarisServiceDiscovery polarisServiceDiscovery(PolarisDiscoveryHandler polarisDiscoveryHandler) {
return new PolarisServiceDiscovery(polarisDiscoveryHandler);
}
}

@ -24,8 +24,6 @@ import java.util.stream.Collectors;
import com.tencent.cloud.common.pojo.PolarisServiceInstance;
import com.tencent.cloud.common.util.DiscoveryUtil;
import com.tencent.cloud.polaris.PolarisDiscoveryProperties;
import com.tencent.cloud.polaris.extend.nacos.NacosContextProperties;
import com.tencent.polaris.api.exception.PolarisException;
import com.tencent.polaris.api.pojo.Instance;
import com.tencent.polaris.api.pojo.ServiceInfo;
@ -40,18 +38,9 @@ import org.springframework.util.CollectionUtils;
*/
public class PolarisServiceDiscovery {
private final NacosContextProperties nacosContextProperties;
private final PolarisDiscoveryProperties polarisDiscoveryProperties;
private final PolarisDiscoveryHandler polarisDiscoveryHandler;
public PolarisServiceDiscovery(
NacosContextProperties nacosContextProperties,
PolarisDiscoveryProperties polarisDiscoveryProperties,
PolarisDiscoveryHandler polarisDiscoveryHandler) {
this.nacosContextProperties = nacosContextProperties;
this.polarisDiscoveryProperties = polarisDiscoveryProperties;
public PolarisServiceDiscovery(PolarisDiscoveryHandler polarisDiscoveryHandler) {
this.polarisDiscoveryHandler = polarisDiscoveryHandler;
}

@ -23,7 +23,6 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
import com.google.common.collect.Sets;
import com.tencent.polaris.api.plugin.registry.AbstractResourceEventListener;
import com.tencent.polaris.api.pojo.Instance;
import com.tencent.polaris.api.pojo.RegistryCacheValue;
@ -33,6 +32,7 @@ import com.tencent.polaris.client.pojo.ServiceInstancesByProto;
import com.tencent.polaris.client.pojo.ServicesByProto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import shade.polaris.com.google.common.collect.Sets;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.context.ApplicationEventPublisher;

@ -26,7 +26,7 @@ import com.tencent.cloud.polaris.PolarisDiscoveryProperties;
import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler;
import com.tencent.polaris.api.pojo.ServiceInstances;
import com.tencent.polaris.api.rpc.InstancesResponse;
import org.apache.commons.lang.StringUtils;
import com.tencent.polaris.api.utils.StringUtils;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;

@ -145,8 +145,8 @@ public class ConsulDiscoveryConfigModifier implements PolarisConfigModifier {
configuration.getProvider().getRegisters().add(registerConfig);
// heartbeat
polarisDiscoveryProperties.setHeartbeatInterval(Long.valueOf(
consulHeartbeatProperties.computeHeartbeatInterval().toStandardDuration().getMillis()).intValue());
polarisDiscoveryProperties.setHeartbeatInterval(
(int) consulHeartbeatProperties.computeHeartbeatInterval().getSeconds());
}
@Override

@ -116,7 +116,7 @@ public final class ConsulDiscoveryUtil {
Assert.notNull(checkPort, "checkPort may not be null");
for (ServerConnectorConfigImpl config : configuration.getGlobal().getServerConnectors()) {
if (org.apache.commons.lang.StringUtils.equals(config.getId(), ID)) {
if (StringUtils.equals(config.getId(), ID)) {
Map<String, String> metadata = config.getMetadata();
NewService.Check check = createCheck(checkPort, consulHeartbeatProperties, properties, tsfCoreProperties);
String checkJson = JacksonUtils.serialize2Json(check);

@ -17,17 +17,14 @@
package com.tencent.cloud.polaris.extend.consul;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.joda.time.Period;
import java.time.Duration;
import com.tencent.polaris.api.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.style.ToStringCreator;
import org.springframework.validation.annotation.Validated;
/**
* Copy from org.springframework.cloud.consul.discovery.HeartbeatProperties.
@ -37,7 +34,6 @@ import org.springframework.validation.annotation.Validated;
* @author Chris Bono
*/
@ConfigurationProperties(prefix = "spring.cloud.consul.discovery.heartbeat")
@Validated
public class ConsulHeartbeatProperties {
private static final Logger LOGGER = LoggerFactory.getLogger(ConsulHeartbeatProperties.class);
@ -45,26 +41,22 @@ public class ConsulHeartbeatProperties {
// [WARN] agent: Check 'service:testConsulApp:xtest:8080' missed TTL, is now critical
boolean enabled = true;
@Min(1)
private int ttlValue = 30;
@NotNull
private String ttlUnit = "s";
@DecimalMin("0.1")
@DecimalMax("0.9")
private double intervalRatio = 2.0 / 3.0;
//TODO: did heartbeatInterval need to be a field?
protected Period computeHeartbeatInterval() {
protected Duration computeHeartbeatInterval() {
// heartbeat rate at ratio * ttl, but no later than ttl -1s and, (under lesser
// priority), no sooner than 1s from now
double interval = ttlValue * intervalRatio;
double max = Math.max(interval, 1);
int ttlMinus1 = ttlValue - 1;
double min = Math.min(ttlMinus1, max);
Period heartbeatInterval = new Period(Math.round(1000 * min));
Duration heartbeatInterval = Duration.ofMillis(Math.round(1000 * min));
LOGGER.debug("Computed heartbeatInterval: " + heartbeatInterval);
return heartbeatInterval;
}
@ -81,27 +73,39 @@ public class ConsulHeartbeatProperties {
this.enabled = enabled;
}
public @Min(1) int getTtlValue() {
public int getTtlValue() {
return this.ttlValue;
}
public void setTtlValue(@Min(1) int ttlValue) {
public void setTtlValue(int ttlValue) {
if (ttlValue < 1) {
LOGGER.error("ttlValue must be at least 1, invalid value: {}", ttlValue);
throw new IllegalArgumentException("ttlValue must be at least 1");
}
this.ttlValue = ttlValue;
}
public @NotNull String getTtlUnit() {
public String getTtlUnit() {
return this.ttlUnit;
}
public void setTtlUnit(@NotNull String ttlUnit) {
public void setTtlUnit(String ttlUnit) {
if (StringUtils.isEmpty(ttlUnit)) {
LOGGER.error("ttlUnit cannot be null or empty");
throw new IllegalArgumentException("ttlUnit cannot be null or empty");
}
this.ttlUnit = ttlUnit;
}
public @DecimalMin("0.1") @DecimalMax("0.9") double getIntervalRatio() {
public double getIntervalRatio() {
return this.intervalRatio;
}
public void setIntervalRatio(@DecimalMin("0.1") @DecimalMax("0.9") double intervalRatio) {
public void setIntervalRatio(double intervalRatio) {
if (intervalRatio < 0.1 || intervalRatio > 0.9) {
LOGGER.error("intervalRatio must be between 0.1 and 0.9, invalid value: {}", intervalRatio);
throw new IllegalArgumentException("intervalRatio must be between 0.1 and 0.9");
}
this.intervalRatio = intervalRatio;
}

@ -25,15 +25,15 @@ import java.util.Objects;
import com.tencent.cloud.common.constant.OrderConstant;
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
import com.tencent.polaris.api.config.plugin.DefaultPlugins;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import com.tencent.polaris.factory.config.ConfigurationImpl;
import com.tencent.polaris.factory.config.consumer.DiscoveryConfigImpl;
import com.tencent.polaris.factory.config.global.ServerConnectorConfigImpl;
import com.tencent.polaris.factory.config.provider.RegisterConfigImpl;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
/**
* {@link PolarisConfigModifier} impl of Nacos.

@ -28,15 +28,15 @@ import com.tencent.cloud.polaris.PolarisDiscoveryProperties;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.cloud.polaris.extend.consul.ConsulDiscoveryProperties;
import com.tencent.cloud.polaris.extend.nacos.NacosContextProperties;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import com.tencent.polaris.client.api.SDKContext;
import org.apache.commons.lang.StringUtils;
import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import static com.tencent.cloud.polaris.extend.nacos.NacosContextProperties.DEFAULT_CLUSTER;
import static com.tencent.cloud.polaris.extend.nacos.NacosContextProperties.DEFAULT_GROUP;

@ -43,12 +43,12 @@ import com.tencent.polaris.api.rpc.InstanceHeartbeatRequest;
import com.tencent.polaris.api.rpc.InstanceRegisterRequest;
import com.tencent.polaris.api.rpc.InstanceRegisterResponse;
import com.tencent.polaris.api.rpc.InstancesResponse;
import com.tencent.polaris.api.utils.StringUtils;
import com.tencent.polaris.client.util.NamedThreadFactory;
import com.tencent.polaris.factory.config.provider.ServiceConfigImpl;
import com.tencent.polaris.metadata.core.TransitiveType;
import com.tencent.polaris.metadata.core.constant.MetadataConstants;
import com.tencent.polaris.metadata.core.manager.CalleeMetadataContainerGroup;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ -17,15 +17,11 @@
package com.tencent.cloud.polaris.registry.tsf;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.registry.PolarisRegistration;
import com.tencent.cloud.polaris.registry.PolarisRegistrationCustomizer;
import com.tencent.polaris.plugins.connector.common.constant.ConsulConstant;
import jakarta.servlet.ServletContext;
import org.springframework.beans.factory.ObjectProvider;
@ -52,14 +48,11 @@ public class TsfServletRegistrationCustomizer implements PolarisRegistrationCust
if (sc != null
&& StringUtils.hasText(sc.getContextPath())
&& StringUtils.hasText(sc.getContextPath().replaceAll("/", ""))) {
Map<String, String> metadata = registration.getMetadata();
Map<String, String> metadata = registration.getExtendedMetadata()
.computeIfAbsent(TAGS_KEY, k -> new HashMap<>());
List<String> tags = Arrays.asList(JacksonUtils.deserialize(metadata.get(TAGS_KEY), String[].class));
if (tags == null) {
tags = new ArrayList<>();
}
tags.add("contextPath=" + sc.getContextPath());
metadata.put(ConsulConstant.MetadataMapKey.TAGS_KEY, JacksonUtils.serialize2Json(tags));
String value = "contextPath=" + sc.getContextPath();
metadata.put(value, value);
}
}
}

@ -0,0 +1,108 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.extend.consul;
import com.tencent.cloud.common.util.inet.PolarisInetUtilsAutoConfiguration;
import com.tencent.cloud.polaris.DiscoveryPropertiesAutoConfiguration;
import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Test for {@link ConsulHeartbeatProperties}.
*
* @author Haotian Zhang
*/
public class ConsulHeartbeatPropertiesTest {
@Test
public void testGettersAndSetters() {
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(PolarisContextAutoConfiguration.class,
PolarisInetUtilsAutoConfiguration.class, DiscoveryPropertiesAutoConfiguration.class))
.withPropertyValues("spring.cloud.consul.enabled=true")
.withPropertyValues("spring.cloud.consul.discovery.heartbeat.ttlValue=60")
.withPropertyValues("spring.cloud.consul.discovery.heartbeat.ttl-unit=m")
.withPropertyValues("spring.cloud.consul.discovery.heartbeat.interval-ratio=0.5");
applicationContextRunner.run(context -> {
assertThat(context).hasSingleBean(ConsulHeartbeatProperties.class);
ConsulHeartbeatProperties heartbeatProperties = context.getBean(ConsulHeartbeatProperties.class);
assertThat(heartbeatProperties.isEnabled()).isTrue();
assertThat(heartbeatProperties.getTtlValue()).isEqualTo(60);
assertThat(heartbeatProperties.getTtlUnit()).isEqualTo("m");
assertThat(heartbeatProperties.getIntervalRatio()).isEqualTo(0.5);
});
}
@Test
public void testTtlValueWrong() {
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(PolarisInetUtilsAutoConfiguration.class, DiscoveryPropertiesAutoConfiguration.class))
.withPropertyValues("spring.cloud.consul.enabled=true")
.withPropertyValues("spring.cloud.consul.discovery.heartbeat.ttlValue=0");
applicationContextRunner.run(context -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.hasRootCauseExactlyInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("ttlValue must be at least 1");
});
}
@Test
public void testTtlUnitWrong() {
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(PolarisInetUtilsAutoConfiguration.class, DiscoveryPropertiesAutoConfiguration.class))
.withPropertyValues("spring.cloud.consul.enabled=true")
.withPropertyValues("spring.cloud.consul.discovery.heartbeat.ttl-unit=");
applicationContextRunner.run(context -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.hasRootCauseExactlyInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("ttlUnit cannot be null or empty");
});
}
@Test
public void testIntervalRatioWrong() {
ApplicationContextRunner applicationContextRunner1 = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(PolarisInetUtilsAutoConfiguration.class, DiscoveryPropertiesAutoConfiguration.class))
.withPropertyValues("spring.cloud.consul.enabled=true")
.withPropertyValues("spring.cloud.consul.discovery.heartbeat.interval-ratio=0");
applicationContextRunner1.run(context -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.hasRootCauseExactlyInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("intervalRatio must be between 0.1 and 0.9");
});
ApplicationContextRunner applicationContextRunner2 = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(PolarisInetUtilsAutoConfiguration.class, DiscoveryPropertiesAutoConfiguration.class))
.withPropertyValues("spring.cloud.consul.enabled=true")
.withPropertyValues("spring.cloud.consul.discovery.heartbeat.interval-ratio=1");
applicationContextRunner2.run(context -> {
assertThat(context).hasFailed();
assertThat(context.getStartupFailure())
.hasRootCauseExactlyInstanceOf(IllegalArgumentException.class)
.hasRootCauseMessage("intervalRatio must be between 0.1 and 0.9");
});
}
}

@ -14,73 +14,12 @@
<name>Spring Cloud Starter Tencent Polaris Ratelimit</name>
<dependencies>
<!-- Spring Cloud Tencent dependencies start -->
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-rpc-enhancement</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-metadata-transfer</artifactId>
</dependency>
<!-- Spring Cloud Tencent dependencies end -->
<!-- Polaris dependencies start -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-ratelimit-factory</artifactId>
<exclusions>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-rule</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-nearby</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-namespace</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-canary</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-set</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-isolated</artifactId>
</exclusion>
<exclusion>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-healthy</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-test-common</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-test-mock-discovery</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Polaris dependencies end -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -93,12 +32,6 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
@ -110,23 +43,5 @@
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -22,8 +22,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.context.ServiceRuleManager;
@ -31,6 +29,8 @@ import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties;
import com.tencent.polaris.specification.api.v1.traffic.manage.RateLimitProto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import shade.polaris.com.google.protobuf.InvalidProtocolBufferException;
import shade.polaris.com.google.protobuf.util.JsonFormat;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;

@ -17,7 +17,6 @@
package com.tencent.cloud.polaris.context;
import com.google.protobuf.StringValue;
import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties;
import com.tencent.cloud.polaris.ratelimit.filter.QuotaCheckServletFilter;
import com.tencent.cloud.polaris.ratelimit.spi.PolarisRateLimiterLimitedFallback;
@ -34,6 +33,7 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import shade.polaris.com.google.protobuf.StringValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

@ -19,7 +19,6 @@ package com.tencent.cloud.polaris.ratelimit.endpoint;
import java.util.Map;
import com.google.protobuf.StringValue;
import com.tencent.cloud.polaris.context.ServiceRuleManager;
import com.tencent.cloud.polaris.ratelimit.config.PolarisRateLimitProperties;
import com.tencent.polaris.specification.api.v1.model.ModelProto;
@ -28,6 +27,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import shade.polaris.com.google.protobuf.StringValue;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

@ -26,9 +26,6 @@ import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.StringValue;
import com.google.protobuf.util.JsonFormat;
import com.tencent.cloud.common.constant.HeaderConstant;
import com.tencent.cloud.common.constant.OrderConstant;
import com.tencent.cloud.common.metadata.MetadataContext;
@ -47,6 +44,9 @@ import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import reactor.core.publisher.Mono;
import shade.polaris.com.google.protobuf.InvalidProtocolBufferException;
import shade.polaris.com.google.protobuf.StringValue;
import shade.polaris.com.google.protobuf.util.JsonFormat;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;

@ -25,9 +25,6 @@ import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.StringValue;
import com.google.protobuf.util.JsonFormat;
import com.tencent.cloud.common.constant.HeaderConstant;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.polaris.context.ServiceRuleManager;
@ -43,6 +40,9 @@ import jakarta.servlet.ServletException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import shade.polaris.com.google.protobuf.InvalidProtocolBufferException;
import shade.polaris.com.google.protobuf.StringValue;
import shade.polaris.com.google.protobuf.util.JsonFormat;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;

@ -15,41 +15,12 @@
<dependencies>
<!-- Spring Cloud Tencent dependencies start -->
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-rpc-enhancement</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-metadata-transfer</artifactId>
</dependency>
<!-- Spring Cloud Tencent dependencies end -->
<!-- Polaris dependencies start -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-rule</artifactId>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-metadata</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-nearby</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>router-namespace</artifactId>
</dependency>
<!-- Polaris dependencies end -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
@ -87,30 +58,6 @@
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -23,9 +23,9 @@ import java.util.Map;
import java.util.Set;
import com.tencent.cloud.common.constant.RouterConstant;
import org.apache.commons.lang.StringUtils;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedCaseInsensitiveMap;
/**

@ -21,11 +21,11 @@ import com.tencent.cloud.common.constant.OrderConstant;
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
import com.tencent.cloud.polaris.router.config.properties.PolarisNearByRouterProperties;
import com.tencent.polaris.api.config.consumer.ServiceRouterConfig;
import com.tencent.polaris.api.utils.StringUtils;
import com.tencent.polaris.factory.config.ConfigurationImpl;
import com.tencent.polaris.plugins.router.healthy.RecoverRouterConfig;
import com.tencent.polaris.plugins.router.nearby.NearbyRouterConfig;
import com.tencent.polaris.specification.api.v1.traffic.manage.RoutingProto;
import org.apache.commons.lang.StringUtils;
/**
* RouterConfigModifier.

@ -71,7 +71,7 @@ public class RouterAutoConfiguration {
}
@Bean
@ConditionalOnProperty(value = "spring.cloud.polaris.router.namespace-router.enabled", matchIfMissing = true)
@ConditionalOnProperty("spring.cloud.polaris.router.namespace-router.enabled")
public NamespaceRouterRequestInterceptor namespaceRouterRequestInterceptor(PolarisNamespaceRouterProperties polarisNamespaceRouterProperties) {
return new NamespaceRouterRequestInterceptor(polarisNamespaceRouterProperties);
}

@ -22,15 +22,15 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageOrBuilder;
import com.google.protobuf.util.JsonFormat;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.context.ServiceRuleManager;
import com.tencent.polaris.specification.api.v1.traffic.manage.RoutingProto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import shade.polaris.com.google.protobuf.InvalidProtocolBufferException;
import shade.polaris.com.google.protobuf.MessageOrBuilder;
import shade.polaris.com.google.protobuf.util.JsonFormat;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;

@ -18,9 +18,10 @@
package com.tencent.cloud.polaris.router;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Sets;
import com.tencent.cloud.common.constant.RouterConstant;
import org.junit.jupiter.api.Test;
@ -74,8 +75,11 @@ public class PolarisRouterContextTest {
PolarisRouterContext routerContext = new PolarisRouterContext();
routerContext.putLabels(RouterConstant.ROUTER_LABELS, labels);
Map<String, String> resolvedLabels = routerContext.getLabels(RouterConstant.ROUTER_LABELS,
Sets.newHashSet("k1", "k2", "k4"));
Set<String> labelKeySet = new HashSet<>();
labelKeySet.add("k1");
labelKeySet.add("k2");
labelKeySet.add("k4");
Map<String, String> resolvedLabels = routerContext.getLabels(RouterConstant.ROUTER_LABELS, labelKeySet);
assertThat(resolvedLabels.size()).isEqualTo(2);
assertThat(resolvedLabels.get("k1")).isEqualTo("v1");

@ -22,11 +22,7 @@
<!-- Polaris dependencies start -->
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-model</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-metadata</artifactId>
<artifactId>polaris-all</artifactId>
</dependency>
<!-- Polaris dependencies end -->
@ -36,52 +32,29 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
<exclusions>
<exclusion>
<artifactId>tomcat-embed-el</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>spring-security-crypto</artifactId>
<groupId>org.springframework.security</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-security-rsa</artifactId>
<groupId>org.springframework.security</groupId>
</exclusion>
</exclusions>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons.lang.version}</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
@ -90,11 +63,6 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
@ -113,35 +81,11 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-test-common</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>uk.org.webcompere</groupId>
<artifactId>system-stubs-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

@ -23,6 +23,8 @@ import java.util.Map;
import java.util.Optional;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import com.tencent.polaris.metadata.core.MessageMetadataContainer;
import com.tencent.polaris.metadata.core.MetadataContainer;
import com.tencent.polaris.metadata.core.MetadataProvider;
@ -31,9 +33,6 @@ import com.tencent.polaris.metadata.core.TransitiveType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import static com.tencent.cloud.common.metadata.MetadataContext.FRAGMENT_DISPOSABLE;
import static com.tencent.cloud.common.metadata.MetadataContext.FRAGMENT_UPSTREAM_DISPOSABLE;
@ -88,7 +87,7 @@ public final class MetadataContextHolder {
metadataContainer.putMetadataStringValue(entry.getKey(), entry.getValue(), TransitiveType.DISPOSABLE);
}
// local trans header
if (StringUtils.hasText(staticMetadataManager.getTransHeader())) {
if (StringUtils.isNotBlank(staticMetadataManager.getTransHeader())) {
String transHeader = staticMetadataManager.getTransHeader();
metadataContainer.putMetadataMapValue(MetadataContext.FRAGMENT_RAW_TRANSHEADERS, transHeader, "", TransitiveType.NONE);
}
@ -159,14 +158,14 @@ public final class MetadataContextHolder {
com.tencent.polaris.metadata.core.manager.MetadataContextHolder.refresh(metadataManager -> {
// caller transitive metadata to local custom transitive metadata
MetadataContainer calleeCustomMetadataContainer = metadataManager.getMetadataContainer(MetadataType.CUSTOM, false);
if (!CollectionUtils.isEmpty(dynamicTransitiveMetadata)) {
if (CollectionUtils.isNotEmpty(dynamicTransitiveMetadata)) {
for (Map.Entry<String, String> entry : dynamicTransitiveMetadata.entrySet()) {
calleeCustomMetadataContainer.putMetadataStringValue(entry.getKey(), entry.getValue(), TransitiveType.PASS_THROUGH);
}
}
// caller disposable metadata to caller custom disposable metadata
MetadataContainer callerCustomMetadataContainer = metadataManager.getMetadataContainer(MetadataType.CUSTOM, true);
if (!CollectionUtils.isEmpty(dynamicDisposableMetadata)) {
if (CollectionUtils.isNotEmpty(dynamicDisposableMetadata)) {
for (Map.Entry<String, String> entry : dynamicDisposableMetadata.entrySet()) {
calleeCustomMetadataContainer.putMetadataStringValue(entry.getKey(), entry.getValue(), TransitiveType.NONE);
callerCustomMetadataContainer.putMetadataStringValue(entry.getKey(), entry.getValue(), TransitiveType.DISPOSABLE);
@ -174,7 +173,7 @@ public final class MetadataContextHolder {
}
// caller application metadata to caller application disposable metadata
MetadataContainer callerApplicationMetadataContainer = metadataManager.getMetadataContainer(MetadataType.APPLICATION, true);
if (!CollectionUtils.isEmpty(dynamicApplicationMetadata)) {
if (CollectionUtils.isNotEmpty(dynamicApplicationMetadata)) {
for (Map.Entry<String, String> entry : dynamicApplicationMetadata.entrySet()) {
callerApplicationMetadataContainer.putMetadataStringValue(entry.getKey(), entry.getValue(), TransitiveType.DISPOSABLE);
}

@ -29,12 +29,11 @@ import java.util.stream.Collectors;
import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
import com.tencent.cloud.common.spi.InstanceMetadataProvider;
import org.apache.commons.lang.StringUtils;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
/**
* manage metadata from env/config file/custom spi.
*

@ -24,7 +24,7 @@ import java.util.Objects;
import com.tencent.polaris.api.pojo.Instance;
import com.tencent.polaris.api.utils.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import com.tencent.polaris.api.utils.StringUtils;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;

@ -20,9 +20,9 @@ package com.tencent.cloud.common.rule;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import org.springframework.util.CollectionUtils;
/**
* The condition operation.

@ -21,6 +21,7 @@ import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import org.slf4j.Logger;
@ -42,6 +43,10 @@ public final class JacksonUtils {
private static final Logger LOG = LoggerFactory.getLogger(JacksonUtils.class);
static {
OM.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
private JacksonUtils() {
}

@ -24,11 +24,11 @@ import java.net.URL;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
* okhttp util.
@ -61,7 +61,7 @@ public final class OkHttpUtil {
conn.setRequestMethod("GET");
conn.setConnectTimeout((int) TimeUnit.SECONDS.toMillis(2));
conn.setReadTimeout((int) TimeUnit.SECONDS.toMillis(2));
if (!CollectionUtils.isEmpty(headers)) {
if (CollectionUtils.isNotEmpty(headers)) {
headers.forEach(conn::setRequestProperty);
}
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
@ -71,7 +71,7 @@ public final class OkHttpUtil {
buffer.append(str);
}
String responseBody = buffer.toString();
if (conn.getResponseCode() == 200 && StringUtils.hasText(responseBody)) {
if (conn.getResponseCode() == 200 && StringUtils.isNotBlank(responseBody)) {
LOGGER.debug("exec get request, url: {} success, response data: {}", url, responseBody);
return true;
}

@ -22,10 +22,9 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import io.netty.handler.codec.http.HttpHeaderNames;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.CollectionUtils;
/**
* the utils for parse label expression.

@ -17,7 +17,7 @@
package com.tencent.cloud.common.util.expresstion;
import org.apache.commons.lang.StringUtils;
import com.tencent.polaris.api.utils.StringUtils;
/**
* Old custom expression resolver like ${http.query.key}${http.header.key}.

@ -17,7 +17,7 @@
package com.tencent.cloud.common.util.expresstion;
import org.apache.commons.lang.StringUtils;
import com.tencent.polaris.api.utils.StringUtils;
/**
* New custom expression resolver like $query.key$header.key.

@ -22,12 +22,10 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.CollectionUtils;
/**
* Parse labels from HttpServletRequest.

@ -22,13 +22,13 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.api.utils.StringUtils;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;

@ -22,9 +22,6 @@ 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 {
/**
@ -32,55 +29,10 @@ public class Tag implements Serializable {
*/
public static final int VERSION = 1;
public enum ControlFlag {
/**
* tag transitive by all services.
*/
@SerializedName("0")
TRANSITIVE,
/**
* tag not used in auth.
*/
@SerializedName("1")
NOT_IN_AUTH,
/**
* tag not used in route.
*/
@SerializedName("2")
NOT_IN_ROUTE,
/**
* tag not used in trace.
*/
@SerializedName("3")
NOT_IN_SLEUTH,
/**
* tag not used in lane.
*/
@SerializedName("4")
NOT_IN_LANE,
/**
* tag not used in unit.
*/
@SerializedName("5")
IN_UNIT
}
@SerializedName("k")
@Expose
private String key;
@SerializedName("v")
@Expose
private String value;
@SerializedName("f")
@Expose
private Set<ControlFlag> flags = new HashSet<>();
public Tag(String key, String value, ControlFlag... flags) {
@ -131,7 +83,6 @@ public class Tag implements Serializable {
return (key == null ? 0 : key.hashCode()) + (flags == null ? 0 : flags.hashCode());
}
@Override
public String toString() {
return "Tag{" +
@ -140,4 +91,38 @@ public class Tag implements Serializable {
", flags=" + flags +
'}';
}
public enum ControlFlag {
/**
* tag transitive by all services.
*/
TRANSITIVE,
/**
* tag not used in auth.
*/
NOT_IN_AUTH,
/**
* tag not used in route.
*/
NOT_IN_ROUTE,
/**
* tag not used in trace.
*/
NOT_IN_SLEUTH,
/**
* tag not used in lane.
*/
NOT_IN_LANE,
/**
* tag not used in unit.
*/
IN_UNIT
}
}

@ -79,11 +79,6 @@
<artifactId>spring-cloud-starter-tencent-discovery-adapter-plugin</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-featureenv-plugin</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-gateway-plugin</artifactId>

@ -77,14 +77,10 @@
<polaris.version>2.0.1.0-SNAPSHOT</polaris.version>
<!-- Dependencies -->
<guava.version>32.0.1-jre</guava.version>
<springdoc.version>2.2.0</springdoc.version>
<mocktio.version>4.9.0</mocktio.version>
<byte-buddy.version>1.12.19</byte-buddy.version>
<jackson.version>2.15.3</jackson.version>
<protobuf-java.version>3.21.7</protobuf-java.version>
<okio.version>3.4.0</okio.version>
<joda-time.version>2.9.9</joda-time.version>
<jackson.version>2.15.4</jackson.version>
<system-stubs-jupiter.version>2.0.2</system-stubs-jupiter.version>
<!-- Maven Plugin Versions -->
@ -181,12 +177,6 @@
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-featureenv-plugin</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-gateway-plugin</artifactId>
@ -224,26 +214,6 @@
</dependency>
<!-- third part framework dependencies -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
<exclusions>
<exclusion>
<artifactId>jsr305</artifactId>
<groupId>com.google.code.findbugs</groupId>
</exclusion>
<exclusion>
<artifactId>animal-sniffer-annotations</artifactId>
<groupId>org.codehaus.mojo</groupId>
</exclusion>
<exclusion>
<artifactId>error_prone_annotations</artifactId>
<groupId>com.google.errorprone</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
@ -256,30 +226,12 @@
<version>${springdoc.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf-java.version}</version>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>${byte-buddy.version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>${okio.version}</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${joda-time.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
@ -303,11 +255,34 @@
<!-- polaris SDK-->
<dependency>
<artifactId>polaris-dependencies</artifactId>
<artifactId>polaris-all</artifactId>
<groupId>com.tencent.polaris</groupId>
<version>${polaris.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<artifactId>polaris-threadlocal</artifactId>
<groupId>com.tencent.polaris</groupId>
<version>${polaris.version}</version>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>connector-nacos</artifactId>
<version>${polaris.version}</version>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-test-common</artifactId>
<version>${polaris.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-test-mock-discovery</artifactId>
<version>${polaris.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>

@ -17,10 +17,9 @@
package com.tencent.cloud.metadata.service.frontend;
import java.util.HashMap;
import java.util.Map;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Component;
/**
@ -33,6 +32,6 @@ public class MetadataMiddleServiceFallback implements MetadataMiddleService {
@Override
public Map<String, Map<String, String>> info() {
return Maps.newHashMap();
return new HashMap<>();
}
}

@ -17,10 +17,9 @@
package com.tencent.cloud.metadata.service.middle;
import java.util.HashMap;
import java.util.Map;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Component;
/**
@ -33,6 +32,6 @@ public class MetadataBackendServiceFallback implements MetadataBackendService {
@Override
public Map<String, Map<String, String>> info() {
return Maps.newHashMap();
return new HashMap<>();
}
}

@ -1,174 +0,0 @@
# 多测试环境样例说明
[English](./README.md) | 简体中文
## 一、部署结构
<img src="./imgs/structs.png"/>
如上图所示,一共有三个环境:
1. 基线环境,包含 FrontService、MiddleService、BackendService
2. feature1 环境,包含 MiddleService、BackendService
3. feature2 环境,包含 FrontService、BackendService
并且在入口处,部署网关服务。
三条请求链路:
1. 基线环境链路Gateway -> FrontService(基线) -> MiddleService(基线) -> BackendService(基线)
2. feature1 环境链路Gateway -> FrontService(基线) -> MiddleService(feature1) -> BackendService(feature1)
3. feature2 环境链路Gateway -> FrontService(feature2) -> MiddleService(基线) -> BackendService(feature2)
## 二、运行样例
无需任何代码变更,直接启动 base、feature1、feature2、featureenv-gateway 下所有应用即可。
应用默认指向北极星官方的体验环境,启动成功后可直接到体验站点查看服务注册数据。
- 管控台地址: http://119.91.66.223:80/
- 账号polaris
- 密码polaris
## 三、测试
### 方式一:客户端打标
#### 基线环境链路
````
curl http://127.0.0.1:9999/featureenv-front-example/router/rest
````
响应结果base 表示基线环境)
````
featureenv-front-example[base] -> featureenv-middle-example[base] -> featureenv-backend-example[base]
````
#### feature1 环境链路
通过 X-Polaris-Metadata-Transitive-featureenv 请求头指定特性环境。
````
curl -H'X-Polaris-Metadata-Transitive-featureenv:feature1' http://127.0.0.1:9999/featureenv-front-example/router/rest
````
响应结果
````
featureenv-front-example[base] -> featureenv-middle-example[feature1] -> featureenv-backend-example[feature1]
````
#### feature2 环境链路
通过 X-Polaris-Metadata-Transitive-featureenv 请求头指定特性环境。
````
curl -H'X-Polaris-Metadata-Transitive-featureenv:feature2' http://127.0.0.1:9999/featureenv-front-example/router/rest
````
响应结果
````
featureenv-front-example[feature2] -> featureenv-middle-example[base] -> featureenv-backend-example[feature2]
````
### 方式二:网关流量染色
模拟一种实际的场景,假设客户端请求有一个 uid 请求参数,期望:
1. uid=1000 的请求打到 feature1 环境
2. uid=2000 的请求打到 feature2 环境
3. 其它 uid 的请求打到基线环境
**配置染色规则**
配置地址http://119.91.66.223:80/#/filegroup-detail?group=featureenv-gateway&namespace=default
修改 rule/staining.json 配置文件,填写以下规则:
````json
{
"rules": [
{
"conditions": [
{
"key": "${http.query.uid}",
"values": [
"1000"
],
"operation": "EQUALS"
}
],
"labels": [
{
"key": "featureenv",
"value": "feature1"
}
]
},
{
"conditions": [
{
"key": "${http.query.uid}",
"values": [
"2000"
],
"operation": "EQUALS"
}
],
"labels": [
{
"key": "featureenv",
"value": "feature2"
}
]
}
]
}
````
填写完后发布配置即可。
#### 基线环境链路
````
curl http://127.0.0.1:9999/featureenv-front-example/router/rest?uid=3000
````
响应结果base 表示基线环境)
````
featureenv-front-example[base] -> featureenv-middle-example[base] -> featureenv-backend-example[base]
````
#### feature1 环境链路
通过 X-Polaris-Metadata-Transitive-featureenv 请求头指定特性环境。
````
curl http://127.0.0.1:9999/featureenv-front-example/router/rest?uid=1000
````
响应结果
````
featureenv-front-example[base] -> featureenv-middle-example[feature1] -> featureenv-backend-example[feature1]
````
#### feature2 环境链路
通过 X-Polaris-Metadata-Transitive-featureenv 请求头指定特性环境。
````
curl http://127.0.0.1:9999/featureenv-front-example/router/rest?uid=2000
````
响应结果
````
featureenv-front-example[feature2] -> featureenv-middle-example[base] -> featureenv-backend-example[feature2]
````

@ -1,179 +0,0 @@
## A Multi-Feature Environment Example
English | [简体中文](./README-zh.md)
## I. Deployment Structure
<img src="./imgs/structs.png" alt="multi-feature environment structure"/>
As shown in the figure above, there are three environments.
1. `baseline` environment, including `FrontService`, `MiddleService`, `BackendService`
2. `feature1` environment, including `MiddleService`, `BackendService`
3. `feature2` environment, including `FrontService`, `BackendService`
And at the entrance, deploy the `gateway` service.
Three request links.
1. `baseline` environment link, `Gateway` -> `FrontService`(baseline) -> `MiddleService`(baseline) -> `BackendService`(
baseline)
2. `feature1` environment link, `Gateway` -> `FrontService`(baseline) -> `MiddleService`(feature1) -> `BackendService`(
feature1)
3. `feature2` environment link, `Gateway` -> `FrontService`(feature2) -> `MiddleService`(baseline) -> `BackendService`(
feature2)
## II. Running
Without any code changes, just start all the applications under `base`, `feature1`, `feature2`, `featureenv-gateway`
directly.
By default, the applications point to the official Polaris experience environment, and you can directly view the service
registration data at the experience site after a successful launch.
- Console address: http://119.91.66.223:80/
- Account: polaris
- Password: polaris
## III. Testing
### Mode 1: Client Request With `featureenv` Label
#### `baseline` environment link
````
curl http://127.0.0.1:9999/featureenv-front-example/router/rest
````
Response results (base indicates baseline environment)
````
featureenv-front-example[base] -> featureenv-middle-example[base] -> featureenv-backend-example[base]
````
#### `feature1` environment link
Specify the feature environment via the `X-Polaris-Metadata-Transitive-featureenv` request header.
````
curl -H'X-Polaris-Metadata-Transitive-featureenv:feature1' http://127.0.0.1:9999/featureenv-front-example/router/rest
````
Response results
````
featureenv-front-example[base] -> featureenv-middle-example[feature1] -> featureenv-backend-example[feature1]
````
#### `feature2` environment link
Specify the feature environment via the `X-Polaris-Metadata-Transitive-featureenv` request header.
````
curl -H'X-Polaris-Metadata-Transitive-featureenv:feature2' http://127.0.0.1:9999/featureenv-front-example/router/rest
````
Response results
````
featureenv-front-example[feature2] -> featureenv-middle-example[base] -> featureenv-backend-example[feature2]
````
### Mode 2: Gateway traffic staining
Simulate a real-world scenario, assuming that the client request has a uid request parameter and expects:
1. `uid=1000` requests hit the `feature1` environment
2. `uid=2000` requests hit the `feature2` environment
3. requests with other uid hit the `baseline` environment
**Configure coloring rules**
Polaris Configuration Address: http://119.91.66.223:80/#/filegroup-detail?group=featureenv-gateway&namespace=default
Modify the `rule/staining.json` configuration file and fill in the following rule:
````json
{
"rules": [
{
"conditions": [
{
"key": "${http.query.uid}",
"values": [
"1000"
],
"operation": "EQUALS"
}
],
"labels": [
{
"key": "featureenv",
"value": "feature1"
}
]
},
{
"conditions": [
{
"key": "${http.query.uid}",
"values": [
"2000"
],
"operation": "EQUALS"
}
],
"labels": [
{
"key": "featureenv",
"value": "feature2"
}
]
}
]
}
````
Just fill out and publish the configuration.
#### `baseline` Environment Link
````
curl http://127.0.0.1:9999/featureenv-front-example/router/rest?uid=3000
````
Response results (base indicates baseline environment)
````
featureenv-front-example[base] -> featureenv-middle-example[base] -> featureenv-backend-example[base]
````
#### `feature1` Environment Link
Specify the feature environment via the `X-Polaris-Metadata-Transitive-featureenv` request header.
````
curl http://127.0.0.1:9999/featureenv-front-example/router/rest?uid=1000
````
Response results
````
featureenv-front-example[base] -> featureenv-middle-example[feature1] -> featureenv-backend-example[feature1]
````
#### `feature2` Environment Link
Specify the feature environment via the `X-Polaris-Metadata-Transitive-featureenv` request header.
````
curl http://127.0.0.1:9999/featureenv-front-example/router/rest?uid=2000
````
Response results
````
featureenv-front-example[feature2] -> featureenv-middle-example[base] -> featureenv-backend-example[feature2]
````

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>base</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>base-backend</artifactId>
</project>

@ -1,43 +0,0 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.router.featureenv.basebackend;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lepdou 2022-07-20
*/
@RestController
@RequestMapping("/router")
public class BackendController {
@Value("${spring.application.name}")
private String appName;
/**
* Get information of callee.
* @return information of callee
*/
@GetMapping("/rest")
public String rest() {
return appName + "[base]";
}
}

@ -1,34 +0,0 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.router.featureenv.basebackend;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author lepdou 2022-07-20
*/
@SpringBootApplication
@EnableFeignClients
public class BaseBackendApplication {
public static void main(String[] args) {
SpringApplication.run(BaseBackendApplication.class, args);
}
}

@ -1,15 +0,0 @@
server:
session-timeout: 1800
port: 10002
spring:
application:
name: featureenv-backend-example
cloud:
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
logging:
level:
org.springframework.cloud.gateway: info
com.tencent.cloud.polaris: debug

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>base</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>base-front</artifactId>
</project>

@ -1,34 +0,0 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.router.featureenv.basefront;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author lepdou 2022-07-20
*/
@SpringBootApplication
@EnableFeignClients
public class BaseFrontApplication {
public static void main(String[] args) {
SpringApplication.run(BaseFrontApplication.class, args);
}
}

@ -1,50 +0,0 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.router.featureenv.basefront;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lepdou 2022-07-20
*/
@RestController
@RequestMapping("/router")
public class FrontController {
@Value("${spring.application.name}")
private String appName;
@Autowired
private MiddleService middleService;
/**
* Get information of callee.
* @return information of callee
*/
@GetMapping("/rest")
public String rest() {
String curName = appName + "[base]";
String resp = middleService.rest();
return curName + " -> " + resp;
}
}

@ -1,32 +0,0 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.router.featureenv.basefront;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @author lepdou 2022-07-20
*/
@FeignClient("featureenv-middle-example")
public interface MiddleService {
@GetMapping("/router/rest")
String rest();
}

@ -1,15 +0,0 @@
server:
session-timeout: 1800
port: 10000
spring:
application:
name: featureenv-front-example
cloud:
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
logging:
level:
org.springframework.cloud.gateway: info
com.tencent.cloud.polaris: debug

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>base</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>base-middle</artifactId>
</project>

@ -1,32 +0,0 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.router.featureenv.basemiddle;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @author lepdou 2022-07-20
*/
@FeignClient("featureenv-backend-example")
public interface BackendService {
@GetMapping("/router/rest")
String rest();
}

@ -1,34 +0,0 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.router.featureenv.basemiddle;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author lepdou 2022-07-20
*/
@SpringBootApplication
@EnableFeignClients
public class BaseMiddleApplication {
public static void main(String[] args) {
SpringApplication.run(BaseMiddleApplication.class, args);
}
}

@ -1,50 +0,0 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.router.featureenv.basemiddle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lepdou 2022-07-20
*/
@RestController
@RequestMapping("/router")
public class MiddleController {
@Value("${spring.application.name}")
private String appName;
@Autowired
private BackendService backendService;
/**
* Get information of callee.
* @return information of callee
*/
@GetMapping("/rest")
public String rest() {
String curName = appName + "[base]";
String resp = backendService.rest();
return curName + " -> " + resp;
}
}

@ -1,15 +0,0 @@
server:
session-timeout: 1800
port: 10001
spring:
application:
name: featureenv-middle-example
cloud:
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
logging:
level:
org.springframework.cloud.gateway: info
com.tencent.cloud.polaris: debug

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-router-featureenv-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>base</artifactId>
<packaging>pom</packaging>
<modules>
<module>base-front</module>
<module>base-middle</module>
<module>base-backend</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>feature1</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>feature1-backend</artifactId>
</project>

@ -1,50 +0,0 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.router.featureenv.feature1backend;
import com.tencent.cloud.common.metadata.StaticMetadataManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lepdou 2022-07-20
*/
@RestController
@RequestMapping("/router")
public class BackendController {
@Autowired
private StaticMetadataManager staticMetadataManager;
@Value("${spring.application.name}")
private String appName;
/**
* Get information of callee.
* @return information of callee
*/
@GetMapping("/rest")
public String rest() {
String featureEnv = staticMetadataManager.getMergedStaticMetadata().get("featureenv");
return appName + "[" + featureEnv + "]";
}
}

@ -1,34 +0,0 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.router.featureenv.feature1backend;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author lepdou 2022-07-20
*/
@SpringBootApplication
@EnableFeignClients
public class Feature1BackendApplication {
public static void main(String[] args) {
SpringApplication.run(Feature1BackendApplication.class, args);
}
}

@ -1,19 +0,0 @@
server:
session-timeout: 1800
port: 11002
spring:
application:
name: featureenv-backend-example
cloud:
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
tencent:
metadata:
content:
featureenv: feature1
logging:
level:
org.springframework.cloud.gateway: info
com.tencent.cloud.polaris: debug

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>feature1</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>feature1-middle</artifactId>
</project>

@ -1,32 +0,0 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.router.featureenv.feature1middle;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @author lepdou 2022-07-20
*/
@FeignClient("featureenv-backend-example")
public interface BackendService {
@GetMapping("/router/rest")
String rest();
}

@ -1,34 +0,0 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.router.featureenv.feature1middle;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author lepdou 2022-07-20
*/
@SpringBootApplication
@EnableFeignClients
public class Feature1MiddleApplication {
public static void main(String[] args) {
SpringApplication.run(Feature1MiddleApplication.class, args);
}
}

@ -1,57 +0,0 @@
/*
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
*
* Copyright (C) 2021 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 com.tencent.cloud.polaris.router.featureenv.feature1middle;
import com.tencent.cloud.common.metadata.StaticMetadataManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lepdou 2022-07-20
*/
@RestController
@RequestMapping("/router")
public class MiddleController {
@Value("${spring.application.name}")
private String appName;
@Autowired
private BackendService backendService;
@Autowired
private StaticMetadataManager staticMetadataManager;
/**
* Get information of callee.
* @return information of callee
*/
@GetMapping("/rest")
public String rest() {
String featureEnv = staticMetadataManager.getMergedStaticMetadata().get("featureenv");
String curName = appName + "[" + featureEnv + "]";
String resp = backendService.rest();
return curName + " -> " + resp;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save