feat:add admin http handler. (#1450)

pull/1451/head
Haotian Zhang 3 weeks ago committed by GitHub
parent 925de766dd
commit 14229e03b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -36,3 +36,4 @@
- [fix:fix actuator name warning from #1428 .](https://github.com/Tencent/spring-cloud-tencent/pull/1431)
- [feat:upgrade api circuit breaker.](https://github.com/Tencent/spring-cloud-tencent/pull/1442)
- [feat: support lossless config from console & support warmup.](https://github.com/Tencent/spring-cloud-tencent/pull/1445)
- [feat:add admin http handler.](https://github.com/Tencent/spring-cloud-tencent/pull/1450)

@ -37,6 +37,7 @@ import com.tencent.polaris.api.core.ConsumerAPI;
import com.tencent.polaris.api.pojo.ServiceKey;
import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory;
import com.tencent.polaris.client.api.SDKContext;
import com.tencent.polaris.client.util.Utils;
import com.tencent.polaris.factory.api.DiscoveryAPIFactory;
import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto;
@ -71,6 +72,8 @@ public class PolarisCircuitBreakerMockServerTest {
private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
private static NamingServer namingServer;
private static SDKContext context;
@BeforeAll
public static void beforeAll() throws IOException {
mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class);
@ -79,18 +82,23 @@ public class PolarisCircuitBreakerMockServerTest {
mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.service"))
.thenReturn(SERVICE_CIRCUIT_BREAKER);
PolarisSDKContextManager.innerDestroy();
namingServer = NamingServer.startNamingServer(-1);
System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort()));
ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_CIRCUIT_BREAKER);
CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder();
InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader().getResourceAsStream("circuitBreakerRule.json");
String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines().collect(Collectors.joining(""));
CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder();
InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader()
.getResourceAsStream("circuitBreakerRule.json");
String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
.collect(Collectors.joining(""));
JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder);
CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build();
CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder().addRules(circuitBreakerRule).build();
CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder()
.addRules(circuitBreakerRule).build();
namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker);
Configuration configuration = TestUtils.configWithEnvAddress();
context = SDKContext.initContextByConfig(configuration);
}
@AfterAll
@ -101,14 +109,15 @@ public class PolarisCircuitBreakerMockServerTest {
if (null != mockedApplicationContextAwareUtils) {
mockedApplicationContextAwareUtils.close();
}
if (null != context) {
context.close();
}
}
@Test
public void testCircuitBreaker() {
Configuration configuration = TestUtils.configWithEnvAddress();
CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration);
ConsumerAPI consumerAPI = DiscoveryAPIFactory.createConsumerAPIByConfig(configuration);
CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByContext(context);
ConsumerAPI consumerAPI = DiscoveryAPIFactory.createConsumerAPIByContext(context);
PolarisCircuitBreakerProperties polarisCircuitBreakerProperties = new PolarisCircuitBreakerProperties();
PolarisCircuitBreakerFactory polarisCircuitBreakerFactory = new PolarisCircuitBreakerFactory(circuitBreakAPI, consumerAPI, polarisCircuitBreakerProperties);
CircuitBreaker cb = polarisCircuitBreakerFactory.create(SERVICE_CIRCUIT_BREAKER);
@ -140,7 +149,8 @@ public class PolarisCircuitBreakerMockServerTest {
assertThat(Mono.error(new RuntimeException("boom")).transform(it -> rcb.run(it, t -> Mono.just("fallback")))
.block()).isEqualTo("fallback");
assertThat(Flux.just("foobar", "hello world").transform(it -> rcb.run(it, t -> Flux.just("fallback", "fallback")))
assertThat(Flux.just("foobar", "hello world")
.transform(it -> rcb.run(it, t -> Flux.just("fallback", "fallback")))
.collectList().block())
.isEqualTo(Arrays.asList("fallback", "fallback"));

@ -17,8 +17,10 @@
package com.tencent.cloud.polaris.circuitbreaker.config;
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
@ -42,6 +44,11 @@ public class PolarisCircuitBreakerBootstrapConfigurationTest {
.withPropertyValues("spring.cloud.polaris.enabled=true")
.withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true");
@BeforeAll
static void beforeAll() {
PolarisSDKContextManager.innerDestroy();
}
@Test
public void testDefaultInitialization() {
this.contextRunner.run(context -> {

@ -19,42 +19,28 @@ package com.tencent.cloud.polaris.circuitbreaker.feign;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import com.google.protobuf.util.JsonFormat;
import com.tencent.cloud.polaris.circuitbreaker.PolarisCircuitBreakerFactory;
import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration;
import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerProperties;
import com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter;
import com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
import com.tencent.polaris.api.core.ConsumerAPI;
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
import com.tencent.polaris.api.pojo.ServiceKey;
import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory;
import com.tencent.polaris.client.util.Utils;
import com.tencent.polaris.factory.api.DiscoveryAPIFactory;
import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto;
import com.tencent.polaris.test.common.TestUtils;
import com.tencent.polaris.test.mock.discovery.NamingServer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
import org.springframework.cloud.client.circuitbreaker.Customizer;
import org.springframework.cloud.client.circuitbreaker.NoFallbackAvailableException;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FallbackFactory;
@ -67,7 +53,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@ -80,6 +65,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
classes = PolarisCircuitBreakerFeignIntegrationTest.TestConfig.class,
properties = {
"spring.cloud.gateway.enabled=false",
"spring.cloud.polaris.address=grpc://127.0.0.1:10081",
"spring.cloud.openfeign.circuitbreaker.enabled=true",
"spring.cloud.polaris.namespace=" + NAMESPACE_TEST,
"spring.cloud.polaris.service=test"
@ -88,6 +74,8 @@ public class PolarisCircuitBreakerFeignIntegrationTest {
private static final String TEST_SERVICE_NAME = "test-service-callee";
private static NamingServer namingServer;
@Autowired
private EchoService echoService;
@ -100,6 +88,31 @@ public class PolarisCircuitBreakerFeignIntegrationTest {
@Autowired
private BazService bazService;
@BeforeAll
static void beforeAll() throws Exception {
PolarisSDKContextManager.innerDestroy();
namingServer = NamingServer.startNamingServer(10081);
ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME);
CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder();
InputStream inputStream = PolarisCircuitBreakerFeignIntegrationTest.class.getClassLoader()
.getResourceAsStream("circuitBreakerRule.json");
String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
.collect(Collectors.joining(""));
JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder);
CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build();
CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder()
.addRules(circuitBreakerRule).build();
namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker);
}
@AfterAll
static void afterAll() {
if (null != namingServer) {
namingServer.terminate();
}
}
@Test
public void contextLoads() {
assertThat(echoService).isNotNull();
@ -168,9 +181,6 @@ public class PolarisCircuitBreakerFeignIntegrationTest {
@EnableFeignClients
public static class TestConfig {
@Autowired(required = false)
private List<Customizer<PolarisCircuitBreakerFactory>> customizers = new ArrayList<>();
@Bean
public EchoServiceFallback echoServiceFallback() {
return new EchoServiceFallback();
@ -180,65 +190,6 @@ public class PolarisCircuitBreakerFeignIntegrationTest {
public CustomFallbackFactory customFallbackFactory() {
return new CustomFallbackFactory();
}
@Bean
public PreDestroy preDestroy(NamingServer namingServer) {
return new PreDestroy(namingServer);
}
@Bean
public NamingServer namingServer() throws IOException {
NamingServer namingServer = NamingServer.startNamingServer(-1);
System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort()));
ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME);
CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder();
InputStream inputStream = PolarisCircuitBreakerFeignIntegrationTest.class.getClassLoader()
.getResourceAsStream("circuitBreakerRule.json");
String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
.collect(Collectors.joining(""));
JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder);
CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build();
CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder()
.addRules(circuitBreakerRule).build();
namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker);
return namingServer;
}
@Bean
public CircuitBreakAPI circuitBreakAPI(NamingServer namingServer) {
com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress();
return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration);
}
@Bean
public ConsumerAPI consumerAPI(NamingServer namingServer) {
com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress();
return DiscoveryAPIFactory.createConsumerAPIByConfig(configuration);
}
@Bean
@ConditionalOnMissingBean(SuccessCircuitBreakerReporter.class)
public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties,
CircuitBreakAPI circuitBreakAPI) {
return new SuccessCircuitBreakerReporter(properties, circuitBreakAPI);
}
@Bean
@ConditionalOnMissingBean(ExceptionCircuitBreakerReporter.class)
public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties,
CircuitBreakAPI circuitBreakAPI) {
return new ExceptionCircuitBreakerReporter(properties, circuitBreakAPI);
}
@Bean
@ConditionalOnMissingBean(CircuitBreakerFactory.class)
public CircuitBreakerFactory polarisCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI,
ConsumerAPI consumerAPI, PolarisCircuitBreakerProperties polarisCircuitBreakerProperties) {
PolarisCircuitBreakerFactory factory = new PolarisCircuitBreakerFactory(circuitBreakAPI, consumerAPI, polarisCircuitBreakerProperties);
customizers.forEach(customizer -> customizer.customize(factory));
return factory;
}
}
public static class EchoServiceFallback implements EchoService {
@ -273,19 +224,4 @@ public class PolarisCircuitBreakerFeignIntegrationTest {
}
}
public static class PreDestroy implements DisposableBean {
private final NamingServer namingServer;
public PreDestroy(NamingServer namingServer) {
this.namingServer = namingServer;
}
@Override
public void destroy() throws Exception {
namingServer.terminate();
}
}
}

@ -19,44 +19,30 @@ package com.tencent.cloud.polaris.circuitbreaker.gateway;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.google.protobuf.util.JsonFormat;
import com.tencent.cloud.polaris.circuitbreaker.PolarisCircuitBreakerFactory;
import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerProperties;
import com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter;
import com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
import com.tencent.polaris.api.core.ConsumerAPI;
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
import com.tencent.polaris.api.pojo.ServiceKey;
import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory;
import com.tencent.polaris.client.util.Utils;
import com.tencent.polaris.factory.api.DiscoveryAPIFactory;
import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto;
import com.tencent.polaris.test.common.TestUtils;
import com.tencent.polaris.test.mock.discovery.NamingServer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import reactor.core.publisher.Mono;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
import org.springframework.cloud.client.circuitbreaker.Customizer;
import org.springframework.cloud.gateway.filter.factory.SpringCloudCircuitBreakerFilterFactory;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
@ -70,7 +56,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV;
import static org.assertj.core.api.Assertions.assertThat;
@ -80,12 +65,6 @@ import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {
"spring.cloud.gateway.enabled=true",
"spring.cloud.polaris.namespace=" + NAMESPACE_TEST,
"spring.cloud.polaris.service=test",
"spring.main.web-application-type=reactive"
},
classes = PolarisCircuitBreakerGatewayIntegrationTest.TestApplication.class
)
@ActiveProfiles("test-gateway")
@ -94,12 +73,39 @@ public class PolarisCircuitBreakerGatewayIntegrationTest {
private static final String TEST_SERVICE_NAME = "test-service-callee";
private static NamingServer namingServer;
@Autowired
private WebTestClient webClient;
@Autowired
private ApplicationContext applicationContext;
@BeforeAll
static void beforeAll() throws Exception {
PolarisSDKContextManager.innerDestroy();
namingServer = NamingServer.startNamingServer(10081);
ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME);
CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder();
InputStream inputStream = PolarisCircuitBreakerGatewayIntegrationTest.class.getClassLoader()
.getResourceAsStream("circuitBreakerRule.json");
String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
.collect(Collectors.joining(""));
JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder);
CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build();
CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder()
.addRules(circuitBreakerRule).build();
namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker);
}
@AfterAll
static void afterAll() {
if (null != namingServer) {
namingServer.terminate();
}
}
@Test
public void fallback() throws Exception {
SpringCloudCircuitBreakerFilterFactory.Config config = new SpringCloudCircuitBreakerFilterFactory.Config();
@ -161,68 +167,6 @@ public class PolarisCircuitBreakerGatewayIntegrationTest {
@EnableAutoConfiguration
public static class TestApplication {
@Autowired(required = false)
private List<Customizer<PolarisCircuitBreakerFactory>> customizers = new ArrayList<>();
@Bean
public PreDestroy preDestroy(NamingServer namingServer) {
return new PreDestroy(namingServer);
}
@Bean
public NamingServer namingServer() throws IOException {
NamingServer namingServer = NamingServer.startNamingServer(-1);
System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort()));
ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME);
CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder();
InputStream inputStream = PolarisCircuitBreakerGatewayIntegrationTest.class.getClassLoader()
.getResourceAsStream("circuitBreakerRule.json");
String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
.collect(Collectors.joining(""));
JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder);
CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build();
CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder()
.addRules(circuitBreakerRule).build();
namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker);
return namingServer;
}
@Bean
public CircuitBreakAPI circuitBreakAPI(NamingServer namingServer) throws IOException {
com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress();
return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration);
}
@Bean
public ConsumerAPI consumerAPI(NamingServer namingServer) {
com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress();
return DiscoveryAPIFactory.createConsumerAPIByConfig(configuration);
}
@Bean
@ConditionalOnMissingBean(SuccessCircuitBreakerReporter.class)
public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties,
CircuitBreakAPI circuitBreakAPI) {
return new SuccessCircuitBreakerReporter(properties, circuitBreakAPI);
}
@Bean
@ConditionalOnMissingBean(ExceptionCircuitBreakerReporter.class)
public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties,
CircuitBreakAPI circuitBreakAPI) {
return new ExceptionCircuitBreakerReporter(properties, circuitBreakAPI);
}
@Bean
@ConditionalOnMissingBean(CircuitBreakerFactory.class)
public CircuitBreakerFactory polarisCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI, ConsumerAPI consumerAPI,
PolarisCircuitBreakerProperties polarisCircuitBreakerProperties) {
PolarisCircuitBreakerFactory factory = new PolarisCircuitBreakerFactory(circuitBreakAPI, consumerAPI, polarisCircuitBreakerProperties);
customizers.forEach(customizer -> customizer.customize(factory));
return factory;
}
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
Set<String> codeSets = new HashSet<>();
@ -265,19 +209,4 @@ public class PolarisCircuitBreakerGatewayIntegrationTest {
}
}
public static class PreDestroy implements DisposableBean {
private final NamingServer namingServer;
public PreDestroy(NamingServer namingServer) {
this.namingServer = namingServer;
}
@Override
public void destroy() throws Exception {
namingServer.terminate();
}
}
}

@ -18,44 +18,31 @@
package com.tencent.cloud.polaris.circuitbreaker.resttemplate;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import com.google.protobuf.util.JsonFormat;
import com.tencent.cloud.polaris.circuitbreaker.PolarisCircuitBreakerFactory;
import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration;
import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerProperties;
import com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter;
import com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter;
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
import com.tencent.polaris.api.pojo.ServiceKey;
import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory;
import com.tencent.polaris.client.util.Utils;
import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto;
import com.tencent.polaris.test.common.TestUtils;
import com.tencent.polaris.test.mock.discovery.NamingServer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
import org.springframework.cloud.client.circuitbreaker.Customizer;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ApplicationContext;
@ -74,7 +61,6 @@ import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.DefaultUriBuilderFactory;
import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@ -90,6 +76,7 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat
classes = PolarisCircuitBreakerRestTemplateIntegrationTest.TestConfig.class,
properties = {
"spring.cloud.gateway.enabled=false",
"spring.cloud.polaris.address=grpc://127.0.0.1:10081",
"feign.circuitbreaker.enabled=true",
"spring.cloud.polaris.namespace=" + NAMESPACE_TEST,
"spring.cloud.polaris.service=test"
@ -98,6 +85,8 @@ public class PolarisCircuitBreakerRestTemplateIntegrationTest {
private static final String TEST_SERVICE_NAME = "test-service-callee";
private static NamingServer namingServer;
@Autowired
@Qualifier("defaultRestTemplate")
private RestTemplate defaultRestTemplate;
@ -125,6 +114,29 @@ public class PolarisCircuitBreakerRestTemplateIntegrationTest {
@Autowired
private ApplicationContext applicationContext;
@BeforeAll
static void beforeAll() throws Exception {
PolarisSDKContextManager.innerDestroy();
namingServer = NamingServer.startNamingServer(10081);
ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME);
CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder();
InputStream inputStream = PolarisCircuitBreakerRestTemplateIntegrationTest.class.getClassLoader()
.getResourceAsStream("circuitBreakerRule.json");
String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
.collect(Collectors.joining(""));
JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder);
CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build();
CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder()
.addRules(circuitBreakerRule).build();
namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker);
}
@AfterAll
static void afterAll() {
if (null != namingServer) {
namingServer.terminate();
}
}
@Test
public void testRestTemplate() throws URISyntaxException {
@ -151,7 +163,8 @@ public class PolarisCircuitBreakerRestTemplateIntegrationTest {
Utils.sleepUninterrupted(2000);
assertThat(restTemplateFallbackFromCode2.getForObject("/example/service/b/info", String.class)).isEqualTo("\"this is a fallback class\"");
Utils.sleepUninterrupted(2000);
assertThat(restTemplateFallbackFromCode3.getForEntity("/example/service/b/info", String.class).getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(restTemplateFallbackFromCode3.getForEntity("/example/service/b/info", String.class)
.getStatusCode()).isEqualTo(HttpStatus.OK);
Utils.sleepUninterrupted(2000);
assertThat(restTemplateFallbackFromCode4.getForObject("/example/service/b/info", String.class)).isEqualTo("fallback");
Utils.sleepUninterrupted(2000);
@ -168,13 +181,6 @@ public class PolarisCircuitBreakerRestTemplateIntegrationTest {
@EnableFeignClients
public static class TestConfig {
@Autowired(required = false)
private List<Customizer<PolarisCircuitBreakerFactory>> customizers = new ArrayList<>();
{
PolarisSDKContextManager.innerDestroy();
}
@Bean
@com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker(fallback = "fallback")
public RestTemplate defaultRestTemplate() {
@ -246,59 +252,6 @@ public class PolarisCircuitBreakerRestTemplateIntegrationTest {
return new CustomPolarisCircuitBreakerFallback3();
}
@Bean
public NamingServer namingServer() throws IOException {
NamingServer namingServer = NamingServer.startNamingServer(-1);
System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort()));
ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME);
CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder();
InputStream inputStream = PolarisCircuitBreakerRestTemplateIntegrationTest.class.getClassLoader()
.getResourceAsStream("circuitBreakerRule.json");
String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
.collect(Collectors.joining(""));
JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder);
CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build();
CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder()
.addRules(circuitBreakerRule).build();
namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker);
return namingServer;
}
@Bean
public PreDestroy preDestroy(NamingServer namingServer) {
return new PreDestroy(namingServer);
}
@Bean
public CircuitBreakAPI circuitBreakAPI(NamingServer namingServer) {
com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress();
return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration);
}
@Bean
@ConditionalOnMissingBean(SuccessCircuitBreakerReporter.class)
public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties,
CircuitBreakAPI circuitBreakAPI) {
return new SuccessCircuitBreakerReporter(properties, circuitBreakAPI);
}
@Bean
@ConditionalOnMissingBean(ExceptionCircuitBreakerReporter.class)
public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties,
CircuitBreakAPI circuitBreakAPI) {
return new ExceptionCircuitBreakerReporter(properties, circuitBreakAPI);
}
@Bean
@ConditionalOnMissingBean(CircuitBreakerFactory.class)
public CircuitBreakerFactory polarisCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI,
PolarisSDKContextManager polarisSDKContextManager, PolarisCircuitBreakerProperties polarisCircuitBreakerProperties) {
PolarisCircuitBreakerFactory factory = new PolarisCircuitBreakerFactory(
circuitBreakAPI, polarisSDKContextManager.getConsumerAPI(), polarisCircuitBreakerProperties);
customizers.forEach(customizer -> customizer.customize(factory));
return factory;
}
@RestController
@RequestMapping("/example/service/b")
public class ServiceBController {
@ -347,19 +300,4 @@ public class PolarisCircuitBreakerRestTemplateIntegrationTest {
);
}
}
public static class PreDestroy implements DisposableBean {
private final NamingServer namingServer;
public PreDestroy(NamingServer namingServer) {
this.namingServer = namingServer;
}
@Override
public void destroy() throws Exception {
namingServer.terminate();
}
}
}

@ -1,22 +1,15 @@
spring:
main:
web-application-type: reactive
application:
name: GatewayScgService
cloud:
tencent:
plugin:
scg:
staining:
enabled: true
rule-staining:
enabled: true
router:
feature-env:
enabled: true
polaris:
address: grpc://127.0.0.1:8091
namespace: default
address: grpc://127.0.0.1:10081
namespace: Test
enabled: true
gateway:
enabled: true
routes:
- id: cb-test
uri: http://localhost:${server.port}/hello/1

@ -63,6 +63,7 @@ public class ConfigurationModifier implements PolarisConfigurationConfigModifier
@Override
public void modify(ConfigurationImpl configuration) {
configuration.getGlobal().getAPI().setReportEnable(false);
configuration.getGlobal().getStatReporter().setEnable(false);
if (!polarisContextProperties.getEnabled() || !polarisConfigProperties.isEnabled()) {
return;

@ -76,7 +76,7 @@ public class LosslessRegistryAspectTest {
.withPropertyValues("spring.cloud.polaris.lossless.enabled=true")
.withPropertyValues("spring.cloud.polaris.lossless.delayRegisterInterval=5000")
.withPropertyValues("spring.cloud.polaris.lossless.healthCheckPath=")
.withPropertyValues("spring.cloud.polaris.lossless.port=" + LOSSLESS_PORT_1)
.withPropertyValues("spring.cloud.polaris.admin.port=" + LOSSLESS_PORT_1)
.withPropertyValues("spring.application.name=" + SERVICE_PROVIDER)
.withPropertyValues("server.port=" + APPLICATION_PORT)
.withPropertyValues("spring.cloud.polaris.localIpAddress=" + HOST)
@ -97,7 +97,7 @@ public class LosslessRegistryAspectTest {
.withPropertyValues("spring.cloud.polaris.lossless.enabled=true")
.withPropertyValues("spring.cloud.polaris.lossless.healthCheckInterval=1000")
.withPropertyValues("spring.cloud.polaris.lossless.healthCheckPath=/test")
.withPropertyValues("spring.cloud.polaris.lossless.port=28082")
.withPropertyValues("spring.cloud.polaris.admin.port=28082")
.withPropertyValues("spring.application.name=" + SERVICE_PROVIDER)
.withPropertyValues("server.port=" + APPLICATION_PORT)
.withPropertyValues("spring.cloud.polaris.localIpAddress=" + HOST)

@ -41,7 +41,7 @@ public class LosslessConfigModifierTest {
.withPropertyValues("spring.cloud.nacos.discovery.enabled=false")
.withPropertyValues("spring.cloud.polaris.enabled=true")
.withPropertyValues("spring.cloud.polaris.lossless.enabled=true")
.withPropertyValues("spring.cloud.polaris.lossless.port=20000")
.withPropertyValues("spring.cloud.polaris.admin.port=20000")
.withPropertyValues("spring.cloud.polaris.lossless.delayRegisterInterval=10")
.withPropertyValues("spring.application.name=test")
.withPropertyValues("spring.cloud.gateway.enabled=false");
@ -51,7 +51,7 @@ public class LosslessConfigModifierTest {
.withPropertyValues("spring.cloud.nacos.discovery.enabled=false")
.withPropertyValues("spring.cloud.polaris.enabled=true")
.withPropertyValues("spring.cloud.polaris.lossless.enabled=true")
.withPropertyValues("spring.cloud.polaris.lossless.port=20000")
.withPropertyValues("spring.cloud.polaris.admin.port=20000")
.withPropertyValues("spring.cloud.polaris.lossless.healthCheckPath=/xxx")
.withPropertyValues("spring.cloud.polaris.lossless.healthCheckInterval=5")
.withPropertyValues("spring.application.name=test")
@ -75,8 +75,6 @@ public class LosslessConfigModifierTest {
PolarisSDKContextManager polarisSDKContextManager = context.getBean(PolarisSDKContextManager.class);
LosslessConfig losslessConfig = polarisSDKContextManager.getSDKContext().
getConfig().getProvider().getLossless();
assertThat(losslessConfig.getHost()).isEqualTo("0.0.0.0");
assertThat(losslessConfig.getPort()).isEqualTo(20000);
assertThat(losslessConfig.getDelayRegisterInterval()).isEqualTo(10);
assertThat(losslessConfig.getStrategy()).isEqualTo(LosslessProto.DelayRegister.DelayStrategy.DELAY_BY_TIME);
});
@ -88,8 +86,6 @@ public class LosslessConfigModifierTest {
PolarisSDKContextManager polarisSDKContextManager = context.getBean(PolarisSDKContextManager.class);
LosslessConfig losslessConfig = polarisSDKContextManager.getSDKContext().
getConfig().getProvider().getLossless();
assertThat(losslessConfig.getHost()).isEqualTo("0.0.0.0");
assertThat(losslessConfig.getPort()).isEqualTo(20000);
assertThat(losslessConfig.getHealthCheckPath()).isEqualTo("/xxx");
assertThat(losslessConfig.getHealthCheckInterval()).isEqualTo(5);
assertThat(losslessConfig.getStrategy()).isEqualTo(LosslessProto.DelayRegister.DelayStrategy.DELAY_BY_HEALTH_CHECK);

@ -177,6 +177,11 @@ public class OrderConstant {
*/
public static Integer LOSSLESS_ORDER = 2;
/**
* Order of admin configuration modifier.
*/
public static Integer ADMIN_ORDER = 2;
/**
* Order of service contract configuration modifier.
*/

@ -47,12 +47,12 @@ public @interface ConditionalOnTsfConsulEnabled {
Environment environment = conditionContext.getEnvironment();
boolean tsfConsulEnable = false;
String tsfAppId = environment.getProperty("tsf_app_id", "");
String tsfAppId = environment.getProperty("tsf_app_id");
if (StringUtils.isNotBlank(tsfAppId)) {
String tsfConsulIp = environment.getProperty("tsf_consul_ip");
String tsePolarisAddress = environment.getProperty("spring.cloud.polaris.address");
if (StringUtils.isBlank(tsePolarisAddress) && StringUtils.isNotBlank(environment.getProperty("tse_polaris_ip"))) {
tsePolarisAddress = "grpc://" + environment.getProperty("tse_polaris_ip") + ":8091";
String tsePolarisAddress = environment.getProperty("polaris_address");
if (StringUtils.isBlank(tsePolarisAddress) && StringUtils.isNotBlank(environment.getProperty("spring.cloud.polaris.address"))) {
tsePolarisAddress = environment.getProperty("spring.cloud.polaris.address");
}
tsfConsulEnable = StringUtils.isNotBlank(tsfConsulIp) && StringUtils.isBlank(tsePolarisAddress);
}

@ -1,50 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.tencent.cloud.common.tsf;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.tencent.polaris.api.utils.StringUtils;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* Condition that if Polaris enabled.
*
* @author Haotian Zhang
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Conditional(ConditionalOnTsfEnabled.OnTsfEnabledCondition.class)
public @interface ConditionalOnTsfEnabled {
class OnTsfEnabledCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
String tsfAppId = conditionContext.getEnvironment().getProperty("tsf_app_id", "");
return StringUtils.isNotBlank(tsfAppId);
}
}
}

@ -15,12 +15,12 @@ spring:
exposure: true
report:
enabled: true
admin:
port: 28084
stat:
enabled: true
port: 28084
lossless:
enabled: true
port: 28084
#healthCheckPath: /actuator/health
#healthCheckInterval: 5000
lossless:

@ -9,9 +9,10 @@ spring:
server-addr: 127.0.0.1:8848
enabled: true
polaris:
admin:
port: 28085
lossless:
enabled: true
port: 28085
healthCheckPath: /actuator/health
healthCheckInterval: 5000
lossless:

@ -15,9 +15,10 @@ spring:
exposure: true
report:
enabled: true
admin:
port: 28083
stat:
enabled: true
port: 28083
# pushgateway:
# enabled: true
# address: 127.0.0.1:9091

@ -20,9 +20,10 @@ spring:
enabled: true
circuitbreaker:
enabled: true
admin:
port: 28082
stat:
enabled: true
port: 28082
# pushgateway:
# enabled: true
# address: 127.0.0.1:9091

@ -14,9 +14,10 @@ spring:
exposure: true
report:
enabled: true
admin:
port: 28081
stat:
enabled: true
port: 28081
gateway:
discovery:
locator:

@ -17,9 +17,10 @@ spring:
exposure: true
report:
enabled: true
admin:
port: 28083
stat:
enabled: true
port: 28083
# pushgateway:
# enabled: true
# address: 127.0.0.1:9091

@ -17,9 +17,10 @@ spring:
exposure: true
report:
enabled: true
admin:
port: 28084
stat:
enabled: true
port: 28084
# pushgateway:
# enabled: true
# address: 127.0.0.1:9091

@ -25,9 +25,10 @@ spring:
enabled: true
circuitbreaker:
enabled: true
admin:
port: 28082
stat:
enabled: true
port: 28082
# pushgateway:
# enabled: true
# address: 127.0.0.1:9091

@ -26,9 +26,10 @@ spring:
exposure: true
report:
enabled: true
admin:
port: 28081
stat:
enabled: true
port: 28081
gateway:
discovery:
locator:

@ -16,7 +16,6 @@
*/
package com.tencent.cloud.tsf.demo.provider;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
@ -30,6 +29,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -84,36 +84,35 @@ public class ProviderController {
}
@RequestMapping(value = "/echo/{param}", method = RequestMethod.GET)
public String echo(@PathVariable String param, HttpServletResponse response) throws IOException {
public ResponseEntity<String> echo(@PathVariable String param) {
int status;
String responseBody;
switch (param) {
case "1xx":
response.setStatus(HttpServletResponse.SC_CONTINUE);
response.getWriter().write("mock 1xx return.");
response.getWriter().flush();
return "mock 1xx return.";
status = HttpServletResponse.SC_CONTINUE;
responseBody = "mock 1xx return.";
break;
case "3xx":
response.setStatus(HttpServletResponse.SC_FOUND);
response.getWriter().write("mock 3xx return.");
response.getWriter().flush();
return "mock 3xx return.";
status = HttpServletResponse.SC_FOUND;
responseBody = "mock 3xx return.";
break;
case "4xx":
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
response.getWriter().write("mock 4xx return.");
response.getWriter().flush();
return "mock 4xx return.";
status = HttpServletResponse.SC_NOT_FOUND;
responseBody = "mock 4xx return.";
break;
case "5xx":
response.setStatus(HttpServletResponse.SC_BAD_GATEWAY);
response.getWriter().write("mock 5xx return.");
response.getWriter().flush();
return "mock 5xx return.";
status = HttpServletResponse.SC_BAD_GATEWAY;
responseBody = "mock 5xx return.";
break;
default:
LOG.info("provider-demo -- request param: [" + param + "]");
String result = "from host-ip: " + getInet4Address() + ", request param: " + param + ", response from " + providerNameConfig.getName();
LOG.info("provider-demo -- provider config name: [" + providerNameConfig.getName() + ']');
LOG.info("provider-demo -- response info: [" + result + "]");
return result;
responseBody = String.format("from host-ip: %s, request param: %s, response from %s",
getInet4Address(), param, providerNameConfig.getName());
status = HttpServletResponse.SC_OK;
break;
}
return ResponseEntity.status(status).body(responseBody);
}
@RequestMapping(value = "/echo/error/{param}", method = RequestMethod.GET)

@ -9,7 +9,6 @@ spring:
enabled: true
stat:
enabled: true
port: 28081
loadbalancer:
strategy: polarisWeightedRandom
tencent:

@ -39,12 +39,18 @@ public class TsfSpanAttributesProvider implements SpanAttributesProvider {
}
ServiceInstance targetServiceInstance = context.getTargetServiceInstance();
if (null != targetServiceInstance && CollectionUtils.isNotEmpty(targetServiceInstance.getMetadata())) {
String nsId = targetServiceInstance.getMetadata().get(TsfMetadataConstants.TSF_NAMESPACE_ID);
attributes.put("remote.namespace-id", StringUtils.defaultString(nsId));
String groupId = targetServiceInstance.getMetadata().get(TsfMetadataConstants.TSF_GROUP_ID);
attributes.put("remote.group-id", StringUtils.defaultString(groupId));
String applicationId = targetServiceInstance.getMetadata().get(TsfMetadataConstants.TSF_APPLICATION_ID);
attributes.put("remote.application-id", StringUtils.defaultString(applicationId));
if (targetServiceInstance.getMetadata().containsKey(TsfMetadataConstants.TSF_NAMESPACE_ID)) {
attributes.put("remote.namespace-id", StringUtils.defaultString(
targetServiceInstance.getMetadata().get(TsfMetadataConstants.TSF_NAMESPACE_ID)));
}
if (targetServiceInstance.getMetadata().containsKey(TsfMetadataConstants.TSF_GROUP_ID)) {
attributes.put("remote.group-id", StringUtils.defaultString(
targetServiceInstance.getMetadata().get(TsfMetadataConstants.TSF_GROUP_ID)));
}
if (targetServiceInstance.getMetadata().containsKey(TsfMetadataConstants.TSF_APPLICATION_ID)) {
attributes.put("remote.application-id", StringUtils.defaultString(
targetServiceInstance.getMetadata().get(TsfMetadataConstants.TSF_APPLICATION_ID)));
}
}
return attributes;
}

@ -18,15 +18,12 @@
package com.tencent.cloud.plugin.trace.tsf;
import com.tencent.cloud.common.tsf.ConditionalOnTsfEnabled;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
@ConditionalOnTsfEnabled
@ConditionalOnProperty(value = "spring.cloud.polaris.trace.enabled", matchIfMissing = true)
public class TsfTracePropertiesAutoConfiguration {

@ -44,7 +44,6 @@ public class LosslessConfigModifier implements PolarisConfigModifier {
LosslessConfigImpl losslessConfig = (LosslessConfigImpl) configuration.getProvider().getLossless();
if (losslessProperties.isEnabled()) {
losslessConfig.setEnable(true);
losslessConfig.setPort(losslessProperties.getPort());
if (Objects.nonNull(losslessProperties.getDelayRegisterInterval())) {
losslessConfig.setDelayRegisterInterval(losslessProperties.getDelayRegisterInterval());
}

@ -25,8 +25,6 @@ public class LosslessProperties {
private boolean enabled = false;
private int port = 28080;
private String healthCheckPath;
private Long delayRegisterInterval;
@ -41,14 +39,6 @@ public class LosslessProperties {
this.enabled = enabled;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getHealthCheckPath() {
return healthCheckPath;
}

@ -3,7 +3,7 @@
{
"name": "spring.cloud.polaris.lossless.enabled",
"type": "java.lang.Boolean",
"defaultValue": true,
"defaultValue": false,
"description": "the switch for lossless plugin."
}
]

@ -0,0 +1,47 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.tencent.cloud.polaris.context.admin;
import com.tencent.cloud.common.constant.OrderConstant.Modifier;
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
import com.tencent.polaris.factory.config.ConfigurationImpl;
/**
* Config modifier for admin.
*
* @author Haotian Zhang
*/
public class PolarisAdminConfigModifier implements PolarisConfigModifier {
private final PolarisAdminProperties polarisAdminProperties;
public PolarisAdminConfigModifier(PolarisAdminProperties polarisAdminProperties) {
this.polarisAdminProperties = polarisAdminProperties;
}
@Override
public void modify(ConfigurationImpl configuration) {
configuration.getGlobal().getAdmin().setHost(this.polarisAdminProperties.getHost());
configuration.getGlobal().getAdmin().setPort(this.polarisAdminProperties.getPort());
}
@Override
public int getOrder() {
return Modifier.ADMIN_ORDER;
}
}

@ -0,0 +1,63 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.tencent.cloud.polaris.context.admin;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Properties for Polaris Admin.
*
* @author Haotian Zhang
*/
@ConfigurationProperties(prefix = "spring.cloud.polaris.admin")
public class PolarisAdminProperties {
/**
* Admin host.
*/
private String host = "0.0.0.0";
/**
* Admin port.
*/
private int port = 28080;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
@Override
public String toString() {
return "PolarisAdminProperties{" +
"host='" + host + '\'' +
", port=" + port +
'}';
}
}

@ -20,12 +20,13 @@ package com.tencent.cloud.polaris.context.config;
import java.util.List;
import com.tencent.cloud.common.tsf.ConditionalOnTsfEnabled;
import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled;
import com.tencent.cloud.polaris.context.ModifyAddress;
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
import com.tencent.cloud.polaris.context.ServiceRuleManager;
import com.tencent.cloud.polaris.context.admin.PolarisAdminConfigModifier;
import com.tencent.cloud.polaris.context.admin.PolarisAdminProperties;
import com.tencent.cloud.polaris.context.config.extend.consul.ConsulProperties;
import com.tencent.cloud.polaris.context.config.extend.tsf.TsfCoreProperties;
import com.tencent.cloud.polaris.context.config.extend.tsf.TsfInstanceMetadataProvider;
@ -69,6 +70,18 @@ public class PolarisContextAutoConfiguration {
return new PolarisContextApplicationEventListener(polarisSDKContextManager);
}
@Bean
@ConditionalOnMissingBean
public PolarisAdminProperties polarisAdminProperties() {
return new PolarisAdminProperties();
}
@Bean
@ConditionalOnMissingBean
public PolarisAdminConfigModifier polarisAdminConfigModifier(PolarisAdminProperties polarisAdminProperties) {
return new PolarisAdminConfigModifier(polarisAdminProperties);
}
@Bean
@ConditionalOnMissingBean
public ConsulProperties consulProperties() {
@ -82,7 +95,6 @@ public class PolarisContextAutoConfiguration {
}
@Bean
@ConditionalOnTsfEnabled
@ConditionalOnMissingBean
public TsfInstanceMetadataProvider tsfInstanceMetadataProvider(TsfCoreProperties tsfCoreProperties) {
return new TsfInstanceMetadataProvider(tsfCoreProperties);

@ -0,0 +1,106 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.tencent.cloud.polaris.context.config;
import java.util.HashMap;
import java.util.Map;
import com.tencent.polaris.api.utils.StringUtils;
import org.apache.commons.logging.Log;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
/**
* Read Polaris env.
*
* @author Haotian Zhang
*/
public final class PolarisContextEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
/**
* run before {@link ConfigDataEnvironmentPostProcessor}.
*/
public static final int ORDER = ConfigDataEnvironmentPostProcessor.ORDER - 2;
private final Log LOGGER;
private PolarisContextEnvironmentPostProcessor(DeferredLogFactory logFactory) {
this.LOGGER = logFactory.getLog(getClass());
}
@Override
public int getOrder() {
return ORDER;
}
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
Map<String, Object> polarisEnvProperties = new HashMap<>();
// polaris_address
String polarisAddress = environment.getProperty("polaris_address");
if (StringUtils.isNotBlank(polarisAddress)) {
polarisEnvProperties.put("spring.cloud.polaris.address", polarisAddress);
}
// polaris_address
String polarisNamespace = environment.getProperty("polaris_namespace");
if (StringUtils.isNotBlank(polarisNamespace)) {
polarisEnvProperties.put("spring.cloud.polaris.namespace", polarisNamespace);
}
// polaris_config_address
String polarisConfigAddress = environment.getProperty("polaris_config_address");
if (StringUtils.isNotBlank(polarisConfigAddress)) {
polarisEnvProperties.put("spring.cloud.polaris.config.address", polarisConfigAddress);
}
// polaris_admin_port
String polarisAdminPort = environment.getProperty("polaris_admin_port");
if (StringUtils.isNotBlank(polarisAdminPort)) {
polarisEnvProperties.put("spring.cloud.polaris.admin.port", polarisAdminPort);
}
// application_version
String applicationVersion = environment.getProperty("tsf_prog_version");
if (StringUtils.isNotBlank(applicationVersion)) {
polarisEnvProperties.put("spring.cloud.polaris.discovery.version", applicationVersion);
}
// region
String region = environment.getProperty("tsf_region");
if (StringUtils.isNotBlank(region)) {
polarisEnvProperties.put("spring.cloud.tencent.metadata.content.region", region);
}
// zone
String zone = environment.getProperty("tsf_zone");
if (StringUtils.isNotBlank(zone)) {
polarisEnvProperties.put("spring.cloud.tencent.metadata.content.zone", zone);
}
MapPropertySource propertySource = new MapPropertySource("polaris-env-properties", polarisEnvProperties);
environment.getPropertySources().addFirst(propertySource);
}
}

@ -0,0 +1,58 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.tencent.cloud.polaris.context.config.extend.tsf;
import java.util.concurrent.atomic.AtomicBoolean;
import com.tencent.polaris.api.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
/**
* Utils for TSF.
*
* @author Haotian Zhang
*/
public final class TsfContextUtils {
private static final Logger LOG = LoggerFactory.getLogger(TsfContextUtils.class);
private static final AtomicBoolean isFirstConfiguration = new AtomicBoolean(true);
private static boolean tsfConsulEnabled = false;
private TsfContextUtils() {
}
public static boolean isTsfConsulEnabled(Environment environment) {
if (environment != null && isFirstConfiguration.compareAndSet(true, false)) {
String tsfConsulIp = environment.getProperty("tsf_consul_ip");
String tsePolarisAddress = environment.getProperty("polaris_address");
if (StringUtils.isBlank(tsePolarisAddress) && StringUtils.isNotBlank(environment.getProperty("spring.cloud.polaris.address"))) {
tsePolarisAddress = environment.getProperty("spring.cloud.polaris.address");
}
tsfConsulEnabled = StringUtils.isNotBlank(tsfConsulIp) && StringUtils.isBlank(tsePolarisAddress);
if (tsfConsulEnabled) {
LOG.info("Tsf Consul is enabled: {}", tsfConsulIp);
}
}
return tsfConsulEnabled;
}
}

@ -61,30 +61,18 @@ public final class TsfCoreEnvironmentPostProcessor implements EnvironmentPostPro
if (StringUtils.isNotBlank(tsfAppId)) {
Map<String, Object> defaultProperties = new HashMap<>();
String tsfConsulIp = environment.getProperty("tsf_consul_ip");
String tsePolarisAddress = environment.getProperty("spring.cloud.polaris.address");
if (StringUtils.isBlank(tsePolarisAddress) && StringUtils.isNotBlank(environment.getProperty("tse_polaris_ip"))) {
tsePolarisAddress = "grpc://" + environment.getProperty("tse_polaris_ip") + ":8091";
}
// tsf_prog_version
String tsfProgVersion = environment.getProperty("tsf_prog_version");
if (StringUtils.isBlank(tsfProgVersion)) {
LOGGER.error("tsf_prog_version is empty");
}
else {
defaultProperties.put("spring.cloud.polaris.discovery.version", tsfProgVersion);
}
// lossless
defaultProperties.put("spring.cloud.polaris.lossless.enabled", true);
defaultProperties.put("spring.cloud.polaris.lossless.port", environment.getProperty("tsf_sctt_extensions_port", "11134"));
// state
defaultProperties.put("spring.cloud.polaris.stat.port", environment.getProperty("tsf_sctt_extensions_port", "11134"));
String polarisAdminPort = environment.getProperty("polaris_admin_port");
if (StringUtils.isNotBlank(polarisAdminPort)) {
defaultProperties.put("spring.cloud.polaris.lossless.enabled", true);
}
boolean tsfConsulEnable = StringUtils.isNotBlank(tsfConsulIp) && StringUtils.isBlank(tsePolarisAddress);
if (tsfConsulEnable) {
if (TsfContextUtils.isTsfConsulEnabled(environment)) {
// tsf_consul_ip
String tsfConsulIp = environment.getProperty("tsf_consul_ip");
if (StringUtils.isBlank(tsfConsulIp)) {
LOGGER.error("tsf_consul_ip is empty");
}
// tsf_consul_port
String tsfConsulPort = environment.getProperty("tsf_consul_port");
if (StringUtils.isBlank(tsfConsulPort)) {
@ -117,9 +105,6 @@ public final class TsfCoreEnvironmentPostProcessor implements EnvironmentPostPro
if (StringUtils.isBlank(tsfNamespaceId)) {
LOGGER.error("tsf_namespace_id is empty");
}
else {
defaultProperties.put("spring.cloud.polaris.namespace", tsfNamespaceId);
}
// context
defaultProperties.put("spring.cloud.polaris.enabled", "true");

@ -44,39 +44,46 @@ public class TsfInstanceMetadataProvider implements InstanceMetadataProvider {
@Override
public Map<String, String> getMetadata() {
return new HashMap<>() {{
put(TsfMetadataConstants.TSF_PROG_VERSION, tsfCoreProperties.getTsfProgVersion());
put(TsfMetadataConstants.TSF_APPLICATION_ID, tsfCoreProperties.getTsfApplicationId());
put(TsfMetadataConstants.TSF_GROUP_ID, tsfCoreProperties.getTsfGroupId());
put(TsfMetadataConstants.TSF_APPLICATION_ID, tsfCoreProperties.getTsfApplicationId());
put(TsfMetadataConstants.TSF_PROG_VERSION, tsfCoreProperties.getTsfProgVersion());
put(TsfMetadataConstants.TSF_GROUP_ID, tsfCoreProperties.getTsfGroupId());
put(TsfMetadataConstants.TSF_NAMESPACE_ID, tsfCoreProperties.getTsfNamespaceId());
put(TsfMetadataConstants.TSF_INSTNACE_ID, tsfCoreProperties.getInstanceId());
put(TsfMetadataConstants.TSF_REGION, tsfCoreProperties.getTsfRegion());
put(TsfMetadataConstants.TSF_ZONE, tsfCoreProperties.getTsfZone());
// 处理预热相关的参数
put(WarmupCons.TSF_START_TIME, String.valueOf(System.currentTimeMillis()));
put(TsfMetadataConstants.TSF_SDK_VERSION, SdkVersion.get());
put(TsfMetadataConstants.TSF_TAGS, JacksonUtils.serialize2Json(tsfCoreProperties.getTsfTags()));
String ipv4Address = PolarisInetUtils.getIpString(false);
if (StringUtils.isNotBlank(ipv4Address)) {
put(TsfMetadataConstants.TSF_ADDRESS_IPV4, ipv4Address);
}
String ipv6Address = PolarisInetUtils.getIpString(true);
if (StringUtils.isNotBlank(ipv6Address)) {
put(TsfMetadataConstants.TSF_ADDRESS_IPV6, ipv6Address);
}
}};
}
HashMap<String, String> tsfMetadata = new HashMap<>();
if (StringUtils.isNotBlank(tsfCoreProperties.getTsfApplicationId())) {
tsfMetadata.put(TsfMetadataConstants.TSF_APPLICATION_ID, tsfCoreProperties.getTsfApplicationId());
}
@Override
public String getRegion() {
return tsfCoreProperties.getTsfRegion();
}
if (StringUtils.isNotBlank(tsfCoreProperties.getTsfProgVersion())) {
tsfMetadata.put(TsfMetadataConstants.TSF_PROG_VERSION, tsfCoreProperties.getTsfProgVersion());
}
@Override
public String getZone() {
return tsfCoreProperties.getTsfZone();
if (StringUtils.isNotBlank(tsfCoreProperties.getTsfGroupId())) {
tsfMetadata.put(TsfMetadataConstants.TSF_GROUP_ID, tsfCoreProperties.getTsfGroupId());
}
if (StringUtils.isNotBlank(tsfCoreProperties.getTsfNamespaceId())) {
tsfMetadata.put(TsfMetadataConstants.TSF_NAMESPACE_ID, tsfCoreProperties.getTsfNamespaceId());
}
if (StringUtils.isNotBlank(tsfCoreProperties.getInstanceId())) {
tsfMetadata.put(TsfMetadataConstants.TSF_INSTNACE_ID, tsfCoreProperties.getInstanceId());
}
if (StringUtils.isNotBlank(tsfCoreProperties.getTsfRegion())) {
tsfMetadata.put(TsfMetadataConstants.TSF_REGION, tsfCoreProperties.getTsfRegion());
}
if (StringUtils.isNotBlank(tsfCoreProperties.getTsfZone())) {
tsfMetadata.put(TsfMetadataConstants.TSF_ZONE, tsfCoreProperties.getTsfZone());
}
tsfMetadata.put(WarmupCons.TSF_START_TIME, String.valueOf(System.currentTimeMillis()));
tsfMetadata.put(TsfMetadataConstants.TSF_SDK_VERSION, SdkVersion.get());
tsfMetadata.put(TsfMetadataConstants.TSF_TAGS, JacksonUtils.serialize2Json(tsfCoreProperties.getTsfTags()));
String ipv4Address = PolarisInetUtils.getIpString(false);
if (StringUtils.isNotBlank(ipv4Address)) {
tsfMetadata.put(TsfMetadataConstants.TSF_ADDRESS_IPV4, ipv4Address);
}
String ipv6Address = PolarisInetUtils.getIpString(true);
if (StringUtils.isNotBlank(ipv6Address)) {
tsfMetadata.put(TsfMetadataConstants.TSF_ADDRESS_IPV6, ipv6Address);
}
return tsfMetadata;
}
}

@ -4,4 +4,5 @@ org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.context.ApplicationListener=\
com.tencent.cloud.polaris.context.logging.PolarisLoggingApplicationListener
org.springframework.boot.env.EnvironmentPostProcessor=\
com.tencent.cloud.polaris.context.config.PolarisContextEnvironmentPostProcessor,\
com.tencent.cloud.polaris.context.config.extend.tsf.TsfCoreEnvironmentPostProcessor

@ -33,16 +33,6 @@ public class PolarisStatProperties {
*/
private boolean enabled = true;
/**
* Local host for prometheus to pull.
*/
private String host;
/**
* Port for prometheus to pull. 0 for random from 20000 to 65535.
*/
private int port = 0;
/**
* Path for prometheus to pull.
*/
@ -67,6 +57,12 @@ public class PolarisStatProperties {
@Value("${spring.cloud.polaris.stat.pushgateway.push-interval:#{30000}}")
private Long pushGatewayPushInterval = 30 * 1000L;
/**
* If push gateway gzip open. default false.
*/
@Value("${spring.cloud.polaris.stat.pushgateway.open-gzip:#{false}}")
private Boolean openGzip = false;
public boolean isEnabled() {
return enabled;
}
@ -75,22 +71,6 @@ public class PolarisStatProperties {
this.enabled = enabled;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getPath() {
return path;
}
@ -122,4 +102,12 @@ public class PolarisStatProperties {
public void setPushGatewayPushInterval(Long pushGatewayPushInterval) {
this.pushGatewayPushInterval = pushGatewayPushInterval;
}
public Boolean getOpenGzip() {
return openGzip;
}
public void setOpenGzip(Boolean openGzip) {
this.openGzip = openGzip;
}
}

@ -23,7 +23,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
/**
* Autoconfiguration of stat reporter.
@ -37,7 +36,7 @@ public class PolarisStatPropertiesAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public StatConfigModifier statReporterConfigModifier(PolarisStatProperties polarisStatProperties, Environment environment) {
return new StatConfigModifier(polarisStatProperties, environment);
public StatConfigModifier statReporterConfigModifier(PolarisStatProperties polarisStatProperties) {
return new StatConfigModifier(polarisStatProperties);
}
}

@ -20,11 +20,9 @@ package com.tencent.cloud.rpc.enhancement.stat.config;
import com.tencent.cloud.common.constant.OrderConstant;
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
import com.tencent.polaris.factory.config.ConfigurationImpl;
import com.tencent.polaris.factory.config.global.StatReporterConfigImpl;
import com.tencent.polaris.plugins.stat.prometheus.handler.PrometheusHandlerConfig;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
import static com.tencent.polaris.api.config.global.StatReporterConfig.DEFAULT_REPORTER_PROMETHEUS;
/**
@ -36,43 +34,31 @@ public class StatConfigModifier implements PolarisConfigModifier {
private final PolarisStatProperties polarisStatProperties;
private final Environment environment;
public StatConfigModifier(PolarisStatProperties polarisStatProperties, Environment environment) {
public StatConfigModifier(PolarisStatProperties polarisStatProperties) {
this.polarisStatProperties = polarisStatProperties;
this.environment = environment;
}
@Override
public void modify(ConfigurationImpl configuration) {
// Turn on stat reporter configuration.
configuration.getGlobal().getStatReporter().setEnable(polarisStatProperties.isEnabled());
PrometheusHandlerConfig prometheusHandlerConfig = configuration.getGlobal().getStatReporter()
.getPluginConfig(DEFAULT_REPORTER_PROMETHEUS, PrometheusHandlerConfig.class);
StatReporterConfigImpl statReporterConfig = configuration.getGlobal().getStatReporter();
statReporterConfig.setEnable(polarisStatProperties.isEnabled());
PrometheusHandlerConfig prometheusHandlerConfig = statReporterConfig.getPluginConfig(DEFAULT_REPORTER_PROMETHEUS, PrometheusHandlerConfig.class);
// Set prometheus plugin.
if (polarisStatProperties.isEnabled()) {
if (polarisStatProperties.isPushGatewayEnabled()) {
// push gateway
prometheusHandlerConfig.setType("push");
prometheusHandlerConfig.setAddress(polarisStatProperties.getPushGatewayAddress());
prometheusHandlerConfig.setPushInterval(polarisStatProperties.getPushGatewayPushInterval());
prometheusHandlerConfig.setOpenGzip(polarisStatProperties.getOpenGzip());
}
else {
// pull metrics
prometheusHandlerConfig.setType("pull");
if (!StringUtils.hasText(polarisStatProperties.getHost())) {
polarisStatProperties.setHost("0.0.0.0");
}
prometheusHandlerConfig.setHost(polarisStatProperties.getHost());
prometheusHandlerConfig.setPort(polarisStatProperties.getPort());
prometheusHandlerConfig.setPath(polarisStatProperties.getPath());
}
}
else {
// Set port to -1 to disable stat plugin.
prometheusHandlerConfig.setPort(-1);
}
configuration.getGlobal().getStatReporter()
.setPluginConfig(DEFAULT_REPORTER_PROMETHEUS, prometheusHandlerConfig);

@ -57,20 +57,28 @@
"name": "spring.cloud.polaris.stat.pushgateway.address",
"type": "java.lang.String",
"description": "PushGateway address.",
"sourceType": "com.tencent.cloud.plugin.pushgateway.PolarisStatPushGatewayProperties"
"sourceType": "com.tencent.cloud.rpc.enhancement.stat.config.PolarisStatProperties"
},
{
"name": "spring.cloud.polaris.stat.pushgateway.enabled",
"type": "java.lang.Boolean",
"description": "If state pushGateway reporter enabled.",
"sourceType": "com.tencent.cloud.plugin.pushgateway.PolarisStatPushGatewayProperties",
"sourceType": "com.tencent.cloud.rpc.enhancement.stat.config.PolarisStatProperties",
"defaultValue": false
},
{
"name": "spring.cloud.polaris.stat.pushgateway.push-interval",
"type": "java.lang.Long",
"description": "Push metrics interval. unit: milliseconds default 30s.",
"sourceType": "com.tencent.cloud.plugin.pushgateway.PolarisStatPushGatewayProperties"
"sourceType": "com.tencent.cloud.rpc.enhancement.stat.config.PolarisStatProperties",
"defaultValue": 30000
},
{
"name": "spring.cloud.polaris.stat.pushgateway.open-gzip",
"type": "java.lang.Boolean",
"description": "If push gateway gzip open. default false.",
"sourceType": "com.tencent.cloud.rpc.enhancement.stat.config.PolarisStatProperties",
"defaultValue": false
}
]
}

@ -35,8 +35,6 @@ public class PolarisStatPropertiesTest {
.withConfiguration(AutoConfigurations.of(PolarisStatPropertiesAutoConfiguration.class))
.withPropertyValues("spring.cloud.polaris.enabled=true")
.withPropertyValues("spring.cloud.polaris.stat.enabled=true")
.withPropertyValues("spring.cloud.polaris.stat.host=127.0.0.1")
.withPropertyValues("spring.cloud.polaris.stat.port=20000")
.withPropertyValues("spring.cloud.polaris.stat.path=/xxx")
.withPropertyValues("spring.cloud.polaris.stat.pushgateway.enabled=true")
.withPropertyValues("spring.cloud.polaris.stat.pushgateway.address=127.0.0.1:9091")
@ -50,8 +48,6 @@ public class PolarisStatPropertiesTest {
assertThat(polarisStatProperties).isNotNull();
assertThat(polarisStatProperties.isEnabled()).isTrue();
assertThat(polarisStatProperties.getHost()).isNotBlank();
assertThat(polarisStatProperties.getPort()).isEqualTo(20000);
assertThat(polarisStatProperties.getPath()).isEqualTo("/xxx");
assertThat(polarisStatProperties.isPushGatewayEnabled()).isTrue();
assertThat(polarisStatProperties.getPushGatewayAddress()).isEqualTo("127.0.0.1:9091");

@ -18,6 +18,7 @@
package com.tencent.cloud.rpc.enhancement.stat.config;
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
import com.tencent.polaris.api.config.global.StatReporterConfig;
import com.tencent.polaris.plugins.stat.prometheus.handler.PrometheusHandlerConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -53,6 +54,7 @@ public class StatConfigModifierTest {
.withPropertyValues("spring.cloud.polaris.stat.pushgateway.enabled=true")
.withPropertyValues("spring.cloud.polaris.stat.pushgateway.address=127.0.0.1:9091")
.withPropertyValues("spring.cloud.polaris.stat.pushgateway.push-interval=1000")
.withPropertyValues("spring.cloud.polaris.stat.pushgateway.open-gzip=true")
.withPropertyValues("spring.application.name=test")
.withPropertyValues("spring.cloud.gateway.enabled=false");
@ -76,8 +78,6 @@ public class StatConfigModifierTest {
.getGlobal().getStatReporter()
.getPluginConfig(DEFAULT_REPORTER_PROMETHEUS, PrometheusHandlerConfig.class);
assertThat(prometheusHandlerConfig.getType()).isEqualTo("pull");
assertThat(prometheusHandlerConfig.getHost()).isEqualTo("127.0.0.1");
assertThat(prometheusHandlerConfig.getPort()).isEqualTo(20000);
assertThat(prometheusHandlerConfig.getPath()).isEqualTo("/xxx");
});
}
@ -92,6 +92,7 @@ public class StatConfigModifierTest {
assertThat(prometheusHandlerConfig.getType()).isEqualTo("push");
assertThat(prometheusHandlerConfig.getAddress()).isEqualTo("127.0.0.1:9091");
assertThat(prometheusHandlerConfig.getPushInterval()).isEqualTo(1000);
assertThat(prometheusHandlerConfig.isOpenGzip()).isTrue();
});
}
@ -99,10 +100,9 @@ public class StatConfigModifierTest {
void testDisabled() {
disabledContextRunner.run(context -> {
PolarisSDKContextManager polarisSDKContextManager = context.getBean(PolarisSDKContextManager.class);
PrometheusHandlerConfig prometheusHandlerConfig = polarisSDKContextManager.getSDKContext().getConfig()
.getGlobal().getStatReporter()
.getPluginConfig(DEFAULT_REPORTER_PROMETHEUS, PrometheusHandlerConfig.class);
assertThat(prometheusHandlerConfig.getPort()).isEqualTo(-1);
StatReporterConfig statReporterConfig = polarisSDKContextManager.getSDKContext().getConfig()
.getGlobal().getStatReporter();
assertThat(statReporterConfig.isEnable()).isFalse();
});
}

Loading…
Cancel
Save