From 1c587b7f833fb543db39b8166fb0941b7dfc112b Mon Sep 17 00:00:00 2001 From: seanyu Date: Thu, 13 Apr 2023 00:34:31 +0800 Subject: [PATCH] refactor --- ...olarisCircuitBreakerAutoConfiguration.java | 16 ++ ...olarisCircuitBreakerAutoConfiguration.java | 16 ++ .../ExceptionCircuitBreakerReporter.java | 97 ++++++++++++ .../SuccessCircuitBreakerReporter.java | 99 ++++++++++++ .../ExceptionCircuitBreakerReporterTest.java | 145 ++++++++++++++++++ .../SuccessCircuitBreakerReporterTest.java | 143 +++++++++++++++++ .../src/main/resources/bootstrap.yml | 4 +- spring-cloud-tencent-rpc-enhancement/pom.xml | 35 ----- .../AbstractPolarisReporterAdapter.java | 35 ++--- .../RpcEnhancementAutoConfiguration.java | 103 +++++-------- .../feign/EnhancedFeignBeanPostProcessor.java | 5 +- .../feign/EnhancedFeignClient.java | 75 ++++++--- .../feign/plugin/EnhancedFeignContext.java | 79 ---------- .../reporter/ExceptionPolarisReporter.java | 130 ---------------- .../reporter/SuccessPolarisReporter.java | 126 --------------- .../DefaultEnhancedPluginRunner.java} | 21 ++- .../EnhancedPlugin.java} | 14 +- .../plugin/EnhancedPluginContext.java | 90 +++++++++++ .../EnhancedPluginRunner.java} | 9 +- .../EnhancedPluginType.java} | 6 +- .../plugin/EnhancedRequestContext.java | 107 +++++++++++++ .../plugin/EnhancedResponseContext.java | 86 +++++++++++ .../reporter/ExceptionPolarisReporter.java | 106 +++++++++++++ .../reporter/SuccessPolarisReporter.java | 106 +++++++++++++ .../EnhancedPolarisRestTemplateReporter.java | 131 ---------------- .../resttemplate/EnhancedRestTemplate.java | 105 +++++++++++++ .../scg/EnhancedGatewayGlobalFilter.java | 111 ++++++++++++++ .../scg/EnhancedPolarisGatewayReporter.java | 129 ---------------- .../webclient/EnhancedWebClientReporter.java | 123 ++++++++------- .../AbstractPolarisReporterAdapterTest.java | 10 ++ .../RpcEnhancementAutoConfigurationTest.java | 12 +- .../RpcEnhancementReporterPropertiesTest.java | 4 +- .../feign/EnhancedFeignClientTest.java | 59 +++---- .../plugin/EnhancedFeignContextTest.java | 46 ------ .../plugin/EnhancedPluginContextTest.java | 134 ++++++++++++++++ .../ExceptionPolarisReporterTest.java | 65 ++++---- .../SuccessPolarisReporterTest.java | 63 ++++---- ...est.java => EnhancedRestTemplateTest.java} | 27 +--- ...a => EnhancedGatewayGlobalFilterTest.java} | 33 +--- .../EnhancedWebClientReporterTest.java | 30 ++-- 40 files changed, 1688 insertions(+), 1047 deletions(-) create mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java create mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java create mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporterTest.java create mode 100644 spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporterTest.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java rename spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/{feign/DefaultEnhancedFeignPluginRunner.java => plugin/DefaultEnhancedPluginRunner.java} (61%) rename spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/{feign/plugin/EnhancedFeignPlugin.java => plugin/EnhancedPlugin.java} (75%) create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java rename spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/{feign/EnhancedFeignPluginRunner.java => plugin/EnhancedPluginRunner.java} (73%) rename spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/{feign/plugin/EnhancedFeignPluginType.java => plugin/EnhancedPluginType.java} (88%) create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedRequestContext.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedResponseContext.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporter.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplate.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilter.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedPolarisGatewayReporter.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContextTest.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContextTest.java rename spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/{feign/plugin/reporter => plugin}/ExceptionPolarisReporterTest.java (74%) rename spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/{feign/plugin/reporter => plugin}/SuccessPolarisReporterTest.java (75%) rename spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/{EnhancedPolarisRestTemplateReporterTest.java => EnhancedRestTemplateTest.java} (83%) rename spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/{EnhancedPolarisGatewayReporterTest.java => EnhancedGatewayGlobalFilterTest.java} (80%) diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java index b73303f78..2c1f9decb 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java @@ -22,6 +22,8 @@ import java.util.List; import com.tencent.cloud.polaris.circuitbreaker.PolarisCircuitBreakerFactory; import com.tencent.cloud.polaris.circuitbreaker.common.CircuitBreakerConfigModifier; +import com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter; +import com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter; import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerRestTemplateBeanPostProcessor; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; @@ -61,6 +63,20 @@ public class PolarisCircuitBreakerAutoConfiguration { return CircuitBreakAPIFactory.createCircuitBreakAPIByContext(polarisContext); } + @Bean + @ConditionalOnMissingBean(SuccessCircuitBreakerReporter.class) + public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties, + SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) { + return new SuccessCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI); + } + + @Bean + @ConditionalOnMissingBean(ExceptionCircuitBreakerReporter.class) + public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties, + SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) { + return new ExceptionCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI); + } + @Bean @ConditionalOnMissingBean(CircuitBreakerFactory.class) public CircuitBreakerFactory polarisCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI, ConsumerAPI consumerAPI) { diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/ReactivePolarisCircuitBreakerAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/ReactivePolarisCircuitBreakerAutoConfiguration.java index fdb89b2c9..f2f509218 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/ReactivePolarisCircuitBreakerAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/ReactivePolarisCircuitBreakerAutoConfiguration.java @@ -22,6 +22,8 @@ import java.util.List; import com.tencent.cloud.polaris.circuitbreaker.ReactivePolarisCircuitBreakerFactory; import com.tencent.cloud.polaris.circuitbreaker.common.CircuitBreakerConfigModifier; +import com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter; +import com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; import com.tencent.polaris.api.core.ConsumerAPI; @@ -59,6 +61,20 @@ public class ReactivePolarisCircuitBreakerAutoConfiguration { return CircuitBreakAPIFactory.createCircuitBreakAPIByContext(polarisContext); } + @Bean + @ConditionalOnMissingBean(SuccessCircuitBreakerReporter.class) + public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties, + SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) { + return new SuccessCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI); + } + + @Bean + @ConditionalOnMissingBean(ExceptionCircuitBreakerReporter.class) + public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties, + SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) { + return new ExceptionCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI); + } + @Bean @ConditionalOnMissingBean(ReactiveCircuitBreakerFactory.class) public ReactiveCircuitBreakerFactory polarisReactiveCircuitBreakerFactory(CircuitBreakAPI circuitBreakAPI, ConsumerAPI consumerAPI) { diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java new file mode 100644 index 000000000..b47c1a4a2 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporter.java @@ -0,0 +1,97 @@ +/* + * 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.circuitbreaker.reporter; + +import java.util.Optional; + +import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; +import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat; +import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; +import com.tencent.polaris.client.api.SDKContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.core.Ordered; + +public class ExceptionCircuitBreakerReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { + + private static final Logger LOG = LoggerFactory.getLogger(ExceptionCircuitBreakerReporter.class); + + private final CircuitBreakAPI circuitBreakAPI; + + public ExceptionCircuitBreakerReporter(RpcEnhancementReporterProperties reportProperties, + SDKContext context, + CircuitBreakAPI circuitBreakAPI) { + super(reportProperties, context); + this.circuitBreakAPI = circuitBreakAPI; + } + + @Override + public String getName() { + return ExceptionCircuitBreakerReporter.class.getName(); + } + + @Override + public EnhancedPluginType getType() { + return EnhancedPluginType.EXCEPTION; + } + + @Override + public void run(EnhancedPluginContext context) throws Throwable { + if (!super.reportProperties.isEnabled()) { + return; + } + + EnhancedRequestContext request = context.getRequest(); + ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance()); + + ResourceStat resourceStat = createInstanceResourceStat( + serviceInstance.getServiceId(), + serviceInstance.getHost(), + serviceInstance.getPort(), + request.getUrl(), + null, + context.getDelay(), + context.getThrowable() + ); + + LOG.debug("Will report CircuitBreaker ResourceStat of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", + resourceStat.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), context.getThrowable().getMessage(), context.getDelay()); + + circuitBreakAPI.report(resourceStat); + + } + + @Override + public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) { + LOG.error("ExceptionCircuitBreakerReporter runs failed. context=[{}].", + context, throwable); + } + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE + 2; + } +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java new file mode 100644 index 000000000..ce5fe2a81 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporter.java @@ -0,0 +1,99 @@ +/* + * 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.circuitbreaker.reporter; + +import java.util.Optional; + +import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; +import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter; +import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat; +import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; +import com.tencent.polaris.client.api.SDKContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.core.Ordered; + + +public class SuccessCircuitBreakerReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { + + private static final Logger LOG = LoggerFactory.getLogger(SuccessPolarisReporter.class); + + private final CircuitBreakAPI circuitBreakAPI; + + public SuccessCircuitBreakerReporter(RpcEnhancementReporterProperties reportProperties, + SDKContext context, + CircuitBreakAPI circuitBreakAPI) { + super(reportProperties, context); + this.circuitBreakAPI = circuitBreakAPI; + } + + @Override + public String getName() { + return SuccessCircuitBreakerReporter.class.getName(); + } + + @Override + public EnhancedPluginType getType() { + return EnhancedPluginType.POST; + } + + @Override + public void run(EnhancedPluginContext context) throws Throwable { + if (!super.reportProperties.isEnabled()) { + return; + } + EnhancedRequestContext request = context.getRequest(); + EnhancedResponseContext response = context.getResponse(); + ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance()); + + ResourceStat resourceStat = createInstanceResourceStat( + serviceInstance.getServiceId(), + serviceInstance.getHost(), + serviceInstance.getPort(), + request.getUrl(), + response.getHttpStatus(), + context.getDelay(), + null + ); + + LOG.debug("Will report CircuitBreaker ResourceStat of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", + resourceStat.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), response.getHttpStatus(), context.getDelay()); + + circuitBreakAPI.report(resourceStat); + } + + @Override + public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) { + LOG.error("SuccessCircuitBreakerReporter runs failed. context=[{}].", + context, throwable); + } + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE + 2; + } +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporterTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporterTest.java new file mode 100644 index 000000000..53e38c9d2 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/ExceptionCircuitBreakerReporterTest.java @@ -0,0 +1,145 @@ +/* + * 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.circuitbreaker.reporter; + +import java.net.URI; + +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; +import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; +import com.tencent.polaris.client.api.SDKContext; +import org.junit.jupiter.api.AfterAll; +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 org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +/** + * ExceptionCircuitBreakerReporterTest. + * + * @author sean yu + */ +@ExtendWith(MockitoExtension.class) +public class ExceptionCircuitBreakerReporterTest { + + private static MockedStatic mockedApplicationContextAwareUtils; + @Mock + private RpcEnhancementReporterProperties reporterProperties; + @Mock + private SDKContext sdkContext; + @InjectMocks + private ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter; + @Mock + private CircuitBreakAPI circuitBreakAPI; + + @BeforeAll + static void beforeAll() { + mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn("unit-test"); + } + + @AfterAll + static void afterAll() { + mockedApplicationContextAwareUtils.close(); + } + + @BeforeEach + void setUp() { + MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; + MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; + } + + @Test + public void testGetName() { + assertThat(exceptionCircuitBreakerReporter.getName()).isEqualTo(ExceptionCircuitBreakerReporter.class.getName()); + } + + @Test + public void testType() { + assertThat(exceptionCircuitBreakerReporter.getType()).isEqualTo(EnhancedPluginType.EXCEPTION); + } + + @Test + public void testRun() throws Throwable { + EnhancedPluginContext context = mock(EnhancedPluginContext.class); + // test not report + exceptionCircuitBreakerReporter.run(context); + verify(context, times(0)).getRequest(); + + doReturn(true).when(reporterProperties).isEnabled(); + + EnhancedPluginContext pluginContext = new EnhancedPluginContext(); + EnhancedRequestContext request = EnhancedRequestContext.builder() + .httpMethod(HttpMethod.GET) + .url(URI.create("http://0.0.0.0/")) + .httpHeaders(new HttpHeaders()) + .build(); + EnhancedResponseContext response = EnhancedResponseContext.builder() + .httpStatus(200) + .build(); + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); + serviceInstance.setServiceId(SERVICE_PROVIDER); + + pluginContext.setRequest(request); + pluginContext.setResponse(response); + pluginContext.setServiceInstance(serviceInstance); + pluginContext.setThrowable(new RuntimeException()); + + exceptionCircuitBreakerReporter.run(pluginContext); + exceptionCircuitBreakerReporter.getOrder(); + exceptionCircuitBreakerReporter.getName(); + exceptionCircuitBreakerReporter.getType(); + } + + @Test + public void testHandlerThrowable() { + // mock request + EnhancedRequestContext request = mock(EnhancedRequestContext.class); + // mock response + EnhancedResponseContext response = mock(EnhancedResponseContext.class); + + EnhancedPluginContext context = new EnhancedPluginContext(); + context.setRequest(request); + context.setResponse(response); + exceptionCircuitBreakerReporter.handlerThrowable(context, new RuntimeException("Mock exception.")); + } +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporterTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporterTest.java new file mode 100644 index 000000000..4dcd3d19e --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/reporter/SuccessCircuitBreakerReporterTest.java @@ -0,0 +1,143 @@ +/* + * 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.circuitbreaker.reporter; + +import java.net.URI; + +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; +import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; +import com.tencent.polaris.client.api.SDKContext; +import org.junit.jupiter.api.AfterAll; +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 org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.http.HttpMethod; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +/** + * SuccessCircuitBreakerReporterTest. + * + * @author sean yu + */ +@ExtendWith(MockitoExtension.class) +public class SuccessCircuitBreakerReporterTest { + + private static MockedStatic mockedApplicationContextAwareUtils; + @Mock + private SDKContext sdkContext; + @Mock + private RpcEnhancementReporterProperties reporterProperties; + @InjectMocks + private SuccessCircuitBreakerReporter successCircuitBreakerReporter; + @Mock + private CircuitBreakAPI circuitBreakAPI; + + @BeforeAll + static void beforeAll() { + mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn("unit-test"); + } + + @AfterAll + static void afterAll() { + mockedApplicationContextAwareUtils.close(); + } + + @BeforeEach + void setUp() { + MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; + MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; + } + + @Test + public void testGetName() { + assertThat(successCircuitBreakerReporter.getName()).isEqualTo(SuccessCircuitBreakerReporter.class.getName()); + } + + @Test + public void testType() { + assertThat(successCircuitBreakerReporter.getType()).isEqualTo(EnhancedPluginType.POST); + } + + @Test + public void testRun() throws Throwable { + + EnhancedPluginContext context = mock(EnhancedPluginContext.class); + // test not report + successCircuitBreakerReporter.run(context); + verify(context, times(0)).getRequest(); + + doReturn(true).when(reporterProperties).isEnabled(); + + EnhancedPluginContext pluginContext = new EnhancedPluginContext(); + EnhancedRequestContext request = EnhancedRequestContext.builder() + .httpMethod(HttpMethod.GET) + .url(URI.create("http://0.0.0.0/")) + .build(); + EnhancedResponseContext response = EnhancedResponseContext.builder() + .httpStatus(200) + .build(); + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); + serviceInstance.setServiceId(SERVICE_PROVIDER); + + pluginContext.setRequest(request); + pluginContext.setResponse(response); + pluginContext.setServiceInstance(serviceInstance); + + successCircuitBreakerReporter.run(pluginContext); + successCircuitBreakerReporter.getOrder(); + successCircuitBreakerReporter.getName(); + successCircuitBreakerReporter.getType(); + } + + @Test + public void testHandlerThrowable() { + // mock request + EnhancedRequestContext request = mock(EnhancedRequestContext.class); + // mock response + EnhancedResponseContext response = mock(EnhancedResponseContext.class); + + EnhancedPluginContext context = new EnhancedPluginContext(); + context.setRequest(request); + context.setResponse(response); + successCircuitBreakerReporter.handlerThrowable(context, new RuntimeException("Mock exception.")); + } +} diff --git a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml index 67168f141..649fd5a34 100644 --- a/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-ratelimit-example/ratelimit-callee-service/src/main/resources/bootstrap.yml @@ -12,7 +12,9 @@ spring: enabled: true rejectRequestTipsFilePath: reject-tips.html maxQueuingTime: 500 - + stat: + enabled: true + port: 28083 management: endpoints: web: diff --git a/spring-cloud-tencent-rpc-enhancement/pom.xml b/spring-cloud-tencent-rpc-enhancement/pom.xml index ec89267ca..bf566a053 100644 --- a/spring-cloud-tencent-rpc-enhancement/pom.xml +++ b/spring-cloud-tencent-rpc-enhancement/pom.xml @@ -32,41 +32,6 @@ - - - com.tencent.polaris - polaris-circuitbreaker-factory - - - com.tencent.polaris - router-rule - - - com.tencent.polaris - router-nearby - - - com.tencent.polaris - router-metadata - - - com.tencent.polaris - router-canary - - - com.tencent.polaris - router-set - - - com.tencent.polaris - router-isolated - - - com.tencent.polaris - router-healthy - - - diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java index fad78250c..d177aad8b 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java @@ -68,7 +68,6 @@ import static org.springframework.http.HttpStatus.VARIANT_ALSO_NEGOTIATES; * @author Elve.Xu 2022-07-11 */ public abstract class AbstractPolarisReporterAdapter { - private static final Logger LOG = LoggerFactory.getLogger(AbstractPolarisReporterAdapter.class); private static final List HTTP_STATUSES = toList(NOT_IMPLEMENTED, BAD_GATEWAY, SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT, HTTP_VERSION_NOT_SUPPORTED, VARIANT_ALSO_NEGOTIATES, @@ -88,13 +87,6 @@ public abstract class AbstractPolarisReporterAdapter { this.context = context; } - public ServiceCallResult createServiceCallResult( - @Nullable String calleeServiceName, URI uri, HttpHeaders requestHeaders, @Nullable HttpHeaders responseHeaders, - @Nullable Integer statusCode, long delay, @Nullable Throwable exception) { - return createServiceCallResult( - calleeServiceName, uri.getHost(), uri.getPort(), uri, requestHeaders, responseHeaders, statusCode, delay, exception); - } - /** * createServiceCallResult. * @param calleeServiceName will pick up url host when null @@ -129,13 +121,6 @@ public abstract class AbstractPolarisReporterAdapter { return resultRequest; } - public ResourceStat createInstanceResourceStat( - @Nullable String calleeServiceName, URI uri, - @Nullable Integer statusCode, long delay, @Nullable Throwable exception) { - return createInstanceResourceStat( - calleeServiceName, uri.getHost(), uri.getPort(), uri, statusCode, delay, exception); - } - /** * createInstanceResourceStat. * @param calleeServiceName will pick up url host when null @@ -261,16 +246,18 @@ public abstract class AbstractPolarisReporterAdapter { } private String getLabels(HttpHeaders headers) { - Collection labels = headers.get(RouterConstant.ROUTER_LABEL_HEADER); - if (CollectionUtils.isNotEmpty(labels) && labels.iterator().hasNext()) { - String label = labels.iterator().next(); - try { - label = URLDecoder.decode(label, UTF_8); - } - catch (UnsupportedEncodingException e) { - LOG.error("unsupported charset exception " + UTF_8, e); + if (headers != null) { + Collection labels = headers.get(RouterConstant.ROUTER_LABEL_HEADER); + if (CollectionUtils.isNotEmpty(labels) && labels.iterator().hasNext()) { + String label = labels.iterator().next(); + try { + label = URLDecoder.decode(label, UTF_8); + } + catch (UnsupportedEncodingException e) { + LOG.error("unsupported charset exception " + UTF_8, e); + } + return RequestLabelUtils.convertLabel(label); } - return RequestLabelUtils.convertLabel(label); } return null; } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java index 5068b521b..0042263b9 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java @@ -22,20 +22,18 @@ import java.util.List; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; -import com.tencent.cloud.rpc.enhancement.feign.DefaultEnhancedFeignPluginRunner; import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignBeanPostProcessor; -import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignPluginRunner; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin; -import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.ExceptionPolarisReporter; -import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.SuccessPolarisReporter; +import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter; +import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter; import com.tencent.cloud.rpc.enhancement.resttemplate.BlockingLoadBalancerClientAspect; -import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedPolarisRestTemplateReporter; -import com.tencent.cloud.rpc.enhancement.scg.EnhancedPolarisGatewayReporter; +import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplate; +import com.tencent.cloud.rpc.enhancement.scg.EnhancedGatewayGlobalFilter; import com.tencent.cloud.rpc.enhancement.webclient.EnhancedWebClientReporter; import com.tencent.cloud.rpc.enhancement.webclient.PolarisLoadBalancerClientRequestTransformer; import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; -import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory; import com.tencent.polaris.client.api.SDKContext; import org.springframework.beans.factory.SmartInitializingSingleton; @@ -69,9 +67,23 @@ import org.springframework.web.reactive.function.client.WebClient; public class RpcEnhancementAutoConfiguration { @Bean - @ConditionalOnMissingBean(CircuitBreakAPI.class) - public CircuitBreakAPI circuitBreakAPI(SDKContext polarisContext) { - return CircuitBreakAPIFactory.createCircuitBreakAPIByContext(polarisContext); + public EnhancedPluginRunner enhancedFeignPluginRunner( + @Autowired(required = false) List enhancedPlugins) { + return new DefaultEnhancedPluginRunner(enhancedPlugins); + } + + @Bean + public SuccessPolarisReporter successPolarisReporter(RpcEnhancementReporterProperties properties, + SDKContext context, + ConsumerAPI consumerAPI) { + return new SuccessPolarisReporter(properties, context, consumerAPI); + } + + @Bean + public ExceptionPolarisReporter exceptionPolarisReporter(RpcEnhancementReporterProperties properties, + SDKContext context, + ConsumerAPI consumerAPI) { + return new ExceptionPolarisReporter(properties, context, consumerAPI); } /** @@ -87,35 +99,10 @@ public class RpcEnhancementAutoConfiguration { protected static class PolarisFeignClientAutoConfiguration { @Bean - public EnhancedFeignPluginRunner enhancedFeignPluginRunner( - @Autowired(required = false) List enhancedFeignPlugins) { - return new DefaultEnhancedFeignPluginRunner(enhancedFeignPlugins); - } - - @Bean - public EnhancedFeignBeanPostProcessor polarisFeignBeanPostProcessor(@Lazy EnhancedFeignPluginRunner pluginRunner) { + public EnhancedFeignBeanPostProcessor polarisFeignBeanPostProcessor(@Lazy EnhancedPluginRunner pluginRunner) { return new EnhancedFeignBeanPostProcessor(pluginRunner); } - @Configuration - static class PolarisReporterConfig { - - @Bean - public SuccessPolarisReporter successPolarisReporter(RpcEnhancementReporterProperties properties, - SDKContext context, - ConsumerAPI consumerAPI, - CircuitBreakAPI circuitBreakAPI) { - return new SuccessPolarisReporter(properties, context, consumerAPI, circuitBreakAPI); - } - - @Bean - public ExceptionPolarisReporter exceptionPolarisReporter(RpcEnhancementReporterProperties properties, - SDKContext context, - ConsumerAPI consumerAPI, - CircuitBreakAPI circuitBreakAPI) { - return new ExceptionPolarisReporter(properties, context, consumerAPI, circuitBreakAPI); - } - } } /** @@ -133,15 +120,12 @@ public class RpcEnhancementAutoConfiguration { private List restTemplates = Collections.emptyList(); @Bean - public EnhancedPolarisRestTemplateReporter enhancedPolarisRestTemplateReporter(RpcEnhancementReporterProperties properties, - SDKContext context, - ConsumerAPI consumerAPI, - CircuitBreakAPI circuitBreakAPI) { - return new EnhancedPolarisRestTemplateReporter(properties, context, consumerAPI, circuitBreakAPI); + public EnhancedRestTemplate enhancedPolarisRestTemplateReporter(@Lazy EnhancedPluginRunner pluginRunner) { + return new EnhancedRestTemplate(pluginRunner); } @Bean - public SmartInitializingSingleton setPolarisReporterForRestTemplate(EnhancedPolarisRestTemplateReporter reporter) { + public SmartInitializingSingleton setPolarisReporterForRestTemplate(EnhancedRestTemplate reporter) { return () -> { for (RestTemplate restTemplate : restTemplates) { restTemplate.getInterceptors().add(reporter); @@ -155,6 +139,7 @@ public class RpcEnhancementAutoConfiguration { public BlockingLoadBalancerClientAspect blockingLoadBalancerClientAspect() { return new BlockingLoadBalancerClientAspect(); } + } /** @@ -165,22 +150,12 @@ public class RpcEnhancementAutoConfiguration { @ConditionalOnClass(name = "org.springframework.web.reactive.function.client.WebClient") protected static class PolarisWebClientAutoConfiguration { - @Bean - @ConditionalOnMissingBean - @ConditionalOnClass(name = "org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerClientRequestTransformer") - public PolarisLoadBalancerClientRequestTransformer polarisLoadBalancerClientRequestTransformer() { - return new PolarisLoadBalancerClientRequestTransformer(); - } - @Autowired(required = false) private List webClientBuilder = Collections.emptyList(); @Bean - public EnhancedWebClientReporter exchangeFilterFunction(RpcEnhancementReporterProperties properties, - SDKContext context, - ConsumerAPI consumerAPI, - CircuitBreakAPI circuitBreakAPI) { - return new EnhancedWebClientReporter(properties, context, consumerAPI, circuitBreakAPI); + public EnhancedWebClientReporter exchangeFilterFunction(@Lazy EnhancedPluginRunner pluginRunner) { + return new EnhancedWebClientReporter(pluginRunner); } @Bean @@ -189,6 +164,14 @@ public class RpcEnhancementAutoConfiguration { webClient.filter(reporter); }); } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnClass(name = "org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerClientRequestTransformer") + public PolarisLoadBalancerClientRequestTransformer polarisLoadBalancerClientRequestTransformer() { + return new PolarisLoadBalancerClientRequestTransformer(); + } + } /** @@ -202,12 +185,10 @@ public class RpcEnhancementAutoConfiguration { @Bean @ConditionalOnClass(name = "org.springframework.cloud.gateway.filter.GlobalFilter") - public EnhancedPolarisGatewayReporter enhancedPolarisGatewayReporter(RpcEnhancementReporterProperties properties, - SDKContext context, - ConsumerAPI consumerAPI, - CircuitBreakAPI circuitBreakAPI) { - return new EnhancedPolarisGatewayReporter(properties, context, consumerAPI, circuitBreakAPI); + public EnhancedGatewayGlobalFilter enhancedPolarisGatewayReporter(@Lazy EnhancedPluginRunner pluginRunner) { + return new EnhancedGatewayGlobalFilter(pluginRunner); } } + } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessor.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessor.java index 1ddbe8146..1aa0abe24 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessor.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignBeanPostProcessor.java @@ -17,6 +17,7 @@ package com.tencent.cloud.rpc.enhancement.feign; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; import feign.Client; import org.springframework.beans.BeansException; @@ -35,11 +36,11 @@ import org.springframework.cloud.openfeign.loadbalancer.RetryableFeignBlockingLo */ public class EnhancedFeignBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware { - private final EnhancedFeignPluginRunner pluginRunner; + private final EnhancedPluginRunner pluginRunner; private BeanFactory factory; - public EnhancedFeignBeanPostProcessor(EnhancedFeignPluginRunner pluginRunner) { + public EnhancedFeignBeanPostProcessor(EnhancedPluginRunner pluginRunner) { this.pluginRunner = pluginRunner; } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java index b01850d4d..e191edfde 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClient.java @@ -18,17 +18,26 @@ package com.tencent.cloud.rpc.enhancement.feign; import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; import feign.Client; import feign.Request; import feign.Request.Options; import feign.Response; -import static com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType.EXCEPTION; -import static com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType.FINALLY; -import static com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType.POST; -import static com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType.PRE; +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; + +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION; +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY; +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST; +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.PRE; import static feign.Util.checkNotNull; /** @@ -40,40 +49,64 @@ public class EnhancedFeignClient implements Client { private final Client delegate; - private final EnhancedFeignPluginRunner pluginRunner; + private final EnhancedPluginRunner pluginRunner; - public EnhancedFeignClient(Client target, EnhancedFeignPluginRunner pluginRunner) { + public EnhancedFeignClient(Client target, EnhancedPluginRunner pluginRunner) { this.delegate = checkNotNull(target, "target"); this.pluginRunner = pluginRunner; } @Override public Response execute(Request request, Options options) throws IOException { - EnhancedFeignContext enhancedFeignContext = new EnhancedFeignContext(); - enhancedFeignContext.setRequest(request); - enhancedFeignContext.setOptions(options); + EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext(); + + HttpHeaders requestHeaders = new HttpHeaders(); + request.headers().forEach((s, strings) -> requestHeaders.addAll(s, new ArrayList<>(strings))); + URI url = URI.create(request.url()); + + EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder() + .httpHeaders(requestHeaders) + .httpMethod(HttpMethod.resolve(request.httpMethod().name())) + .url(url) + .build(); + enhancedPluginContext.setRequest(enhancedRequestContext); - // Run pre enhanced feign plugins. - pluginRunner.run(PRE, enhancedFeignContext); + // Run pre enhanced plugins. + pluginRunner.run(PRE, enhancedPluginContext); + long startMillis = System.currentTimeMillis(); try { - long startMillis = System.currentTimeMillis(); Response response = delegate.execute(request, options); - enhancedFeignContext.setDelay(System.currentTimeMillis() - startMillis); - enhancedFeignContext.setResponse(response); + enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); + + HttpHeaders responseHeaders = new HttpHeaders(); + response.headers().forEach((s, strings) -> responseHeaders.addAll(s, new ArrayList<>(strings))); + + EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder() + .httpStatus(response.status()) + .httpHeaders(responseHeaders) + .build(); + enhancedPluginContext.setResponse(enhancedResponseContext); + + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); + serviceInstance.setServiceId(request.requestTemplate().feignTarget().name()); + serviceInstance.setHost(url.getHost()); + serviceInstance.setPort(url.getPort()); + enhancedPluginContext.setServiceInstance(serviceInstance); - // Run post enhanced feign plugins. - pluginRunner.run(POST, enhancedFeignContext); + // Run post enhanced plugins. + pluginRunner.run(POST, enhancedPluginContext); return response; } catch (IOException origin) { - enhancedFeignContext.setException(origin); + enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); + enhancedPluginContext.setThrowable(origin); // Run exception enhanced feign plugins. - pluginRunner.run(EXCEPTION, enhancedFeignContext); + pluginRunner.run(EXCEPTION, enhancedPluginContext); throw origin; } finally { - // Run finally enhanced feign plugins. - pluginRunner.run(FINALLY, enhancedFeignContext); + // Run finally enhanced plugins. + pluginRunner.run(FINALLY, enhancedPluginContext); } } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java deleted file mode 100644 index d1d9aded3..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContext.java +++ /dev/null @@ -1,79 +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.rpc.enhancement.feign.plugin; - -import feign.Request; -import feign.Response; - -/** - * Context used by EnhancedFeignPlugin. - * - * @author Haotian Zhang - */ -public class EnhancedFeignContext { - - private Request request; - - private Request.Options options; - - private Response response; - - private Exception exception; - - private long delay; - - public Request getRequest() { - return request; - } - - public void setRequest(Request request) { - this.request = request; - } - - public Request.Options getOptions() { - return options; - } - - public void setOptions(Request.Options options) { - this.options = options; - } - - public Response getResponse() { - return response; - } - - public void setResponse(Response response) { - this.response = response; - } - - public Exception getException() { - return exception; - } - - public void setException(Exception exception) { - this.exception = exception; - } - - public long getDelay() { - return delay; - } - - public void setDelay(long delay) { - this.delay = delay; - } -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java deleted file mode 100644 index efffcff7d..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporter.java +++ /dev/null @@ -1,130 +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.rpc.enhancement.feign.plugin.reporter; - -import java.net.URI; -import java.util.ArrayList; - -import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat; -import com.tencent.polaris.api.rpc.ServiceCallResult; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; -import com.tencent.polaris.client.api.SDKContext; -import feign.Request; -import feign.Response; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.springframework.core.Ordered; -import org.springframework.http.HttpHeaders; - -/** - * Polaris reporter when feign call fails. - * - * @author Haotian Zhang - */ -public class ExceptionPolarisReporter extends AbstractPolarisReporterAdapter implements EnhancedFeignPlugin { - - private static final Logger LOG = LoggerFactory.getLogger(ExceptionPolarisReporter.class); - private final RpcEnhancementReporterProperties reporterProperties; - - private final ConsumerAPI consumerAPI; - - private final CircuitBreakAPI circuitBreakAPI; - - public ExceptionPolarisReporter(RpcEnhancementReporterProperties reporterProperties, - SDKContext context, - ConsumerAPI consumerAPI, - CircuitBreakAPI circuitBreakAPI) { - super(reporterProperties, context); - this.reporterProperties = reporterProperties; - this.consumerAPI = consumerAPI; - this.circuitBreakAPI = circuitBreakAPI; - } - - @Override - public String getName() { - return ExceptionPolarisReporter.class.getName(); - } - - @Override - public EnhancedFeignPluginType getType() { - return EnhancedFeignPluginType.EXCEPTION; - } - - @Override - public void run(EnhancedFeignContext context) { - if (!reporterProperties.isEnabled()) { - return; - } - - Request request = context.getRequest(); - Response response = context.getResponse(); - Exception exception = context.getException(); - long delay = context.getDelay(); - - HttpHeaders requestHeaders = new HttpHeaders(); - request.headers().forEach((s, strings) -> requestHeaders.addAll(s, new ArrayList<>(strings))); - HttpHeaders responseHeaders = new HttpHeaders(); - Integer status = null; - if (response != null) { - response.headers().forEach((s, strings) -> responseHeaders.addAll(s, new ArrayList<>(strings))); - status = response.status(); - } - - ServiceCallResult resultRequest = createServiceCallResult( - request.requestTemplate().feignTarget().name(), - URI.create(request.url()), - requestHeaders, - responseHeaders, - status, - delay, - exception - ); - LOG.debug("Will report result of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", - resultRequest.getRetStatus().name(), request.httpMethod().name(), request.url(), status, delay); - consumerAPI.updateServiceCallResult(resultRequest); - - ResourceStat resourceStat = createInstanceResourceStat( - request.requestTemplate().feignTarget().name(), - URI.create(request.url()), - status, - delay, - exception - ); - circuitBreakAPI.report(resourceStat); - - } - - @Override - public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { - Request request = context.getRequest(); - Response response = context.getResponse(); - LOG.error("ExceptionPolarisReporter runs failed. Request=[{}]. Response=[{}].", request, response, throwable); - } - - @Override - public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE + 1; - } -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java deleted file mode 100644 index 41de7ae83..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporter.java +++ /dev/null @@ -1,126 +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.rpc.enhancement.feign.plugin.reporter; - -import java.net.URI; -import java.util.ArrayList; - -import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat; -import com.tencent.polaris.api.rpc.ServiceCallResult; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; -import com.tencent.polaris.client.api.SDKContext; -import feign.Request; -import feign.Response; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.springframework.core.Ordered; -import org.springframework.http.HttpHeaders; - -/** - * Polaris reporter when feign call is successful. - * - * @author Haotian Zhang - */ -public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter implements EnhancedFeignPlugin { - - private static final Logger LOG = LoggerFactory.getLogger(SuccessPolarisReporter.class); - - private final ConsumerAPI consumerAPI; - - private final CircuitBreakAPI circuitBreakAPI; - - public SuccessPolarisReporter(RpcEnhancementReporterProperties properties, - SDKContext context, - ConsumerAPI consumerAPI, - CircuitBreakAPI circuitBreakAPI) { - super(properties, context); - this.consumerAPI = consumerAPI; - this.circuitBreakAPI = circuitBreakAPI; - } - - @Override - public String getName() { - return SuccessPolarisReporter.class.getName(); - } - - @Override - public EnhancedFeignPluginType getType() { - return EnhancedFeignPluginType.POST; - } - - @Override - public void run(EnhancedFeignContext context) { - if (!reportProperties.isEnabled()) { - return; - } - - Request request = context.getRequest(); - Response response = context.getResponse(); - long delay = context.getDelay(); - HttpHeaders requestHeaders = new HttpHeaders(); - request.headers().forEach((s, strings) -> requestHeaders.addAll(s, new ArrayList<>(strings))); - HttpHeaders responseHeaders = new HttpHeaders(); - Integer status = null; - if (response != null) { - response.headers().forEach((s, strings) -> responseHeaders.addAll(s, new ArrayList<>(strings))); - status = response.status(); - } - - ServiceCallResult resultRequest = createServiceCallResult( - request.requestTemplate().feignTarget().name(), - URI.create(request.url()), - requestHeaders, - responseHeaders, - status, - delay, - null - ); - LOG.debug("Will report result of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", - resultRequest.getRetStatus().name(), request.httpMethod().name(), request.url(), status, delay); - consumerAPI.updateServiceCallResult(resultRequest); - - ResourceStat resourceStat = createInstanceResourceStat( - request.requestTemplate().feignTarget().name(), - URI.create(request.url()), - status, - delay, - null - ); - circuitBreakAPI.report(resourceStat); - - } - - @Override - public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { - Request request = context.getRequest(); - Response response = context.getResponse(); - LOG.error("SuccessPolarisReporter runs failed. Request=[{}]. Response=[{}].", request, response, throwable); - } - - @Override - public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE + 1; - } -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/DefaultEnhancedFeignPluginRunner.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java similarity index 61% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/DefaultEnhancedFeignPluginRunner.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java index dbaf7d580..ca34b2af1 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/DefaultEnhancedFeignPluginRunner.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java @@ -16,16 +16,13 @@ * */ -package com.tencent.cloud.rpc.enhancement.feign; +package com.tencent.cloud.rpc.enhancement.plugin; import java.util.Comparator; import java.util.List; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; import org.springframework.util.CollectionUtils; @@ -34,14 +31,14 @@ import org.springframework.util.CollectionUtils; * * @author Derek Yi 2022-08-16 */ -public class DefaultEnhancedFeignPluginRunner implements EnhancedFeignPluginRunner { +public class DefaultEnhancedPluginRunner implements EnhancedPluginRunner { - private final Multimap pluginMap = ArrayListMultimap.create(); + private final Multimap pluginMap = ArrayListMultimap.create(); - public DefaultEnhancedFeignPluginRunner(List enhancedFeignPlugins) { - if (!CollectionUtils.isEmpty(enhancedFeignPlugins)) { - enhancedFeignPlugins.stream() - .sorted(Comparator.comparing(EnhancedFeignPlugin::getOrder)) + public DefaultEnhancedPluginRunner(List enhancedPlugins) { + if (!CollectionUtils.isEmpty(enhancedPlugins)) { + enhancedPlugins.stream() + .sorted(Comparator.comparing(EnhancedPlugin::getOrder)) .forEach(plugin -> pluginMap.put(plugin.getType().name(), plugin)); } } @@ -53,8 +50,8 @@ public class DefaultEnhancedFeignPluginRunner implements EnhancedFeignPluginRunn * @param context context in enhanced feign client. */ @Override - public void run(EnhancedFeignPluginType pluginType, EnhancedFeignContext context) { - for (EnhancedFeignPlugin plugin : pluginMap.get(pluginType.name())) { + public void run(EnhancedPluginType pluginType, EnhancedPluginContext context) { + for (EnhancedPlugin plugin : pluginMap.get(pluginType.name())) { try { plugin.run(context); } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPlugin.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPlugin.java similarity index 75% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPlugin.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPlugin.java index 1ecc3d355..39bce26a3 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPlugin.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPlugin.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.rpc.enhancement.feign.plugin; +package com.tencent.cloud.rpc.enhancement.plugin; import org.springframework.core.Ordered; @@ -24,7 +24,7 @@ import org.springframework.core.Ordered; * * @author Haotian Zhang */ -public interface EnhancedFeignPlugin extends Ordered { +public interface EnhancedPlugin extends Ordered { /** * Get name of plugin. @@ -38,9 +38,9 @@ public interface EnhancedFeignPlugin extends Ordered { /** * Get type of plugin. * - * @return {@link EnhancedFeignPluginType} + * @return {@link EnhancedPluginType} */ - EnhancedFeignPluginType getType(); + EnhancedPluginType getType(); /** * Run the plugin. @@ -48,15 +48,15 @@ public interface EnhancedFeignPlugin extends Ordered { * @param context context in enhanced feign client. * @throws Throwable throwable thrown from run method. */ - void run(EnhancedFeignContext context) throws Throwable; + void run(EnhancedPluginContext context) throws Throwable; /** - * Handler throwable from {@link EnhancedFeignPlugin#run(EnhancedFeignContext)}. + * Handler throwable from {@link EnhancedPlugin#run(EnhancedPluginContext)}. * * @param context context in enhanced feign client. * @param throwable throwable thrown from run method. */ - default void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { + default void handlerThrowable(EnhancedPluginContext context, Throwable throwable) { } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java new file mode 100644 index 000000000..fa4e891d0 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java @@ -0,0 +1,90 @@ +/* + * 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.rpc.enhancement.plugin; + + +import org.springframework.cloud.client.ServiceInstance; + +/** + * Context used by EnhancedPlugin. + * + * @author Haotian Zhang + */ +public class EnhancedPluginContext { + + private EnhancedRequestContext request; + + private EnhancedResponseContext response; + + private Throwable throwable; + + private long delay; + + private ServiceInstance serviceInstance; + + public EnhancedRequestContext getRequest() { + return request; + } + + public void setRequest(EnhancedRequestContext request) { + this.request = request; + } + + public EnhancedResponseContext getResponse() { + return response; + } + + public void setResponse(EnhancedResponseContext response) { + this.response = response; + } + + public Throwable getThrowable() { + return throwable; + } + + public void setThrowable(Throwable throwable) { + this.throwable = throwable; + } + + public long getDelay() { + return delay; + } + + public void setDelay(long delay) { + this.delay = delay; + } + + public ServiceInstance getServiceInstance() { + return serviceInstance; + } + + public void setServiceInstance(ServiceInstance serviceInstance) { + this.serviceInstance = serviceInstance; + } + + @Override + public String toString() { + return "EnhancedPluginContext{" + + "request=" + request + + ", response=" + response + + ", throwable=" + throwable + + ", delay=" + delay + + ", serviceInstance=" + serviceInstance + + '}'; + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignPluginRunner.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java similarity index 73% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignPluginRunner.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java index b821827b2..e15af39e5 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignPluginRunner.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java @@ -16,17 +16,14 @@ * */ -package com.tencent.cloud.rpc.enhancement.feign; - -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; +package com.tencent.cloud.rpc.enhancement.plugin; /** * Plugin runner. * * @author Derek Yi 2022-08-16 */ -public interface EnhancedFeignPluginRunner { +public interface EnhancedPluginRunner { /** * run the plugin. @@ -34,5 +31,5 @@ public interface EnhancedFeignPluginRunner { * @param pluginType type of plugin * @param context context in enhanced feign client. */ - void run(EnhancedFeignPluginType pluginType, EnhancedFeignContext context); + void run(EnhancedPluginType pluginType, EnhancedPluginContext context); } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPluginType.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java similarity index 88% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPluginType.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java index fef181d83..64dc2ecb9 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignPluginType.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java @@ -15,14 +15,14 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.rpc.enhancement.feign.plugin; +package com.tencent.cloud.rpc.enhancement.plugin; /** - * Type of EnhancedFeignPlugin. + * Type of EnhancedPlugin. * * @author Haotian Zhang */ -public enum EnhancedFeignPluginType { +public enum EnhancedPluginType { /** * Pre feign plugin. diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedRequestContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedRequestContext.java new file mode 100644 index 000000000..74c9aff63 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedRequestContext.java @@ -0,0 +1,107 @@ +/* + * 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.rpc.enhancement.plugin; + +import java.net.URI; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; + +/** + * EnhancedRequestContext. + * + * @author sean yu + */ +public class EnhancedRequestContext { + + private HttpMethod httpMethod; + + private HttpHeaders httpHeaders; + + private URI url; + + public HttpMethod getHttpMethod() { + return httpMethod; + } + + public void setHttpMethod(HttpMethod httpMethod) { + this.httpMethod = httpMethod; + } + + public HttpHeaders getHttpHeaders() { + return httpHeaders; + } + + public void setHttpHeaders(HttpHeaders httpHeaders) { + this.httpHeaders = httpHeaders; + } + + public URI getUrl() { + return url; + } + + public void setUrl(URI url) { + this.url = url; + } + + public static EnhancedContextRequestBuilder builder() { + return new EnhancedContextRequestBuilder(); + } + + @Override + public String toString() { + return "EnhancedRequestContext{" + + "httpMethod=" + httpMethod + + ", httpHeaders=" + httpHeaders + + ", url=" + url + + '}'; + } + + public static final class EnhancedContextRequestBuilder { + private HttpMethod httpMethod; + private HttpHeaders httpHeaders; + private URI url; + + private EnhancedContextRequestBuilder() { + } + + public EnhancedContextRequestBuilder httpMethod(HttpMethod httpMethod) { + this.httpMethod = httpMethod; + return this; + } + + public EnhancedContextRequestBuilder httpHeaders(HttpHeaders httpHeaders) { + this.httpHeaders = httpHeaders; + return this; + } + + public EnhancedContextRequestBuilder url(URI url) { + this.url = url; + return this; + } + + public EnhancedRequestContext build() { + EnhancedRequestContext enhancedRequestContext = new EnhancedRequestContext(); + enhancedRequestContext.httpMethod = this.httpMethod; + enhancedRequestContext.url = this.url; + enhancedRequestContext.httpHeaders = this.httpHeaders; + return enhancedRequestContext; + } + } + +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedResponseContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedResponseContext.java new file mode 100644 index 000000000..c8773776a --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedResponseContext.java @@ -0,0 +1,86 @@ +/* + * 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.rpc.enhancement.plugin; + +import org.springframework.http.HttpHeaders; + +/** + * EnhancedResponseContext. + * + * @author sean yu + */ +public class EnhancedResponseContext { + + private Integer httpStatus; + + private HttpHeaders httpHeaders; + + public Integer getHttpStatus() { + return httpStatus; + } + + public void setHttpStatus(Integer httpStatus) { + this.httpStatus = httpStatus; + } + + public HttpHeaders getHttpHeaders() { + return httpHeaders; + } + + public void setHttpHeaders(HttpHeaders httpHeaders) { + this.httpHeaders = httpHeaders; + } + + public static EnhancedContextResponseBuilder builder() { + return new EnhancedContextResponseBuilder(); + } + + @Override + public String toString() { + return "EnhancedResponseContext{" + + "httpStatus=" + httpStatus + + ", httpHeaders=" + httpHeaders + + '}'; + } + + public static final class EnhancedContextResponseBuilder { + private Integer httpStatus; + private HttpHeaders httpHeaders; + + private EnhancedContextResponseBuilder() { + } + + public EnhancedContextResponseBuilder httpStatus(Integer httpStatus) { + this.httpStatus = httpStatus; + return this; + } + + public EnhancedContextResponseBuilder httpHeaders(HttpHeaders httpHeaders) { + this.httpHeaders = httpHeaders; + return this; + } + + public EnhancedResponseContext build() { + EnhancedResponseContext enhancedResponseContext = new EnhancedResponseContext(); + enhancedResponseContext.setHttpStatus(httpStatus); + enhancedResponseContext.setHttpHeaders(httpHeaders); + return enhancedResponseContext; + } + } + +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java new file mode 100644 index 000000000..76c4250b3 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/ExceptionPolarisReporter.java @@ -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.rpc.enhancement.plugin.reporter; + + +import java.util.Optional; + +import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.api.rpc.ServiceCallResult; +import com.tencent.polaris.client.api.SDKContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.core.Ordered; + +/** + * Polaris reporter when feign call fails. + * + * @author Haotian Zhang + */ +public class ExceptionPolarisReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { + + private static final Logger LOG = LoggerFactory.getLogger(ExceptionPolarisReporter.class); + + private final ConsumerAPI consumerAPI; + + public ExceptionPolarisReporter(RpcEnhancementReporterProperties reporterProperties, + SDKContext context, + ConsumerAPI consumerAPI) { + super(reporterProperties, context); + this.consumerAPI = consumerAPI; + } + + @Override + public String getName() { + return ExceptionPolarisReporter.class.getName(); + } + + @Override + public EnhancedPluginType getType() { + return EnhancedPluginType.EXCEPTION; + } + + @Override + public void run(EnhancedPluginContext context) { + if (!super.reportProperties.isEnabled()) { + return; + } + + EnhancedRequestContext request = context.getRequest(); + ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance()); + + ServiceCallResult resultRequest = createServiceCallResult( + serviceInstance.getServiceId(), + serviceInstance.getHost(), + serviceInstance.getPort(), + request.getUrl(), + request.getHttpHeaders(), + null, + null, + context.getDelay(), + context.getThrowable() + ); + + LOG.debug("Will report ServiceCallResult of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", + resultRequest.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), context.getThrowable().getMessage(), context.getDelay()); + + consumerAPI.updateServiceCallResult(resultRequest); + + } + + @Override + public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) { + LOG.error("ExceptionPolarisReporter runs failed. context=[{}].", + context, throwable); + } + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE + 1; + } + +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java new file mode 100644 index 000000000..4b35396da --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/reporter/SuccessPolarisReporter.java @@ -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.rpc.enhancement.plugin.reporter; + +import java.util.Optional; + +import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.api.rpc.ServiceCallResult; +import com.tencent.polaris.client.api.SDKContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.core.Ordered; + +/** + * Polaris reporter when feign call is successful. + * + * @author Haotian Zhang + */ +public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { + + private static final Logger LOG = LoggerFactory.getLogger(SuccessPolarisReporter.class); + + private final ConsumerAPI consumerAPI; + + public SuccessPolarisReporter(RpcEnhancementReporterProperties properties, + SDKContext context, + ConsumerAPI consumerAPI) { + super(properties, context); + this.consumerAPI = consumerAPI; + } + + @Override + public String getName() { + return SuccessPolarisReporter.class.getName(); + } + + @Override + public EnhancedPluginType getType() { + return EnhancedPluginType.POST; + } + + @Override + public void run(EnhancedPluginContext context) { + if (!super.reportProperties.isEnabled()) { + return; + } + + EnhancedRequestContext request = context.getRequest(); + EnhancedResponseContext response = context.getResponse(); + ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()).orElse(new DefaultServiceInstance()); + + ServiceCallResult resultRequest = createServiceCallResult( + serviceInstance.getServiceId(), + serviceInstance.getHost(), + serviceInstance.getPort(), + request.getUrl(), + request.getHttpHeaders(), + response.getHttpHeaders(), + response.getHttpStatus(), + context.getDelay(), + null + ); + + LOG.debug("Will report ServiceCallResult of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", + resultRequest.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), response.getHttpStatus(), context.getDelay()); + + consumerAPI.updateServiceCallResult(resultRequest); + + } + + @Override + public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) { + LOG.error("SuccessPolarisReporter runs failed. context=[{}].", + context, throwable); + } + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE + 1; + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporter.java deleted file mode 100644 index 0fc20200a..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporter.java +++ /dev/null @@ -1,131 +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.rpc.enhancement.resttemplate; - -import java.io.IOException; -import java.net.SocketTimeoutException; -import java.util.Map; - -import com.tencent.cloud.common.constant.HeaderConstant; -import com.tencent.cloud.common.metadata.MetadataContextHolder; -import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat; -import com.tencent.polaris.api.rpc.ServiceCallResult; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; -import com.tencent.polaris.client.api.SDKContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; - -/** - * EnhancedPolarisRestTemplateReporter. - * - * @author sean yu - */ -public class EnhancedPolarisRestTemplateReporter extends AbstractPolarisReporterAdapter implements ClientHttpRequestInterceptor { - - private static final Logger LOG = LoggerFactory.getLogger(EnhancedPolarisRestTemplateReporter.class); - - private final ConsumerAPI consumerAPI; - - private final CircuitBreakAPI circuitBreakAPI; - - - /** - * Constructor With {@link RpcEnhancementReporterProperties} . - * - * @param reportProperties instance of {@link RpcEnhancementReporterProperties}. - */ - public EnhancedPolarisRestTemplateReporter(RpcEnhancementReporterProperties reportProperties, - SDKContext context, - ConsumerAPI consumerAPI, - CircuitBreakAPI circuitBreakAPI) { - super(reportProperties, context); - this.consumerAPI = consumerAPI; - this.circuitBreakAPI = circuitBreakAPI; - } - - - @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { - if (!reportProperties.isEnabled()) { - return execution.execute(request, body); - } - - long startTime = System.currentTimeMillis(); - ClientHttpResponse response = null; - IOException ex = null; - try { - response = execution.execute(request, body); - } - catch (SocketTimeoutException e) { - ex = e; - } - HttpHeaders requestHeaders = request.getHeaders(); - HttpHeaders responseHeaders = null; - Integer status = null; - if (response != null) { - responseHeaders = response.getHeaders(); - status = response.getRawStatusCode(); - } - - Map loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata(); - String targetHost = loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST); - Integer targetPort = loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT) != null ? Integer.valueOf(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT)) : null; - long delay = System.currentTimeMillis() - startTime; - - ServiceCallResult resultRequest = createServiceCallResult( - request.getURI().getHost(), - targetHost, - targetPort, - request.getURI(), - requestHeaders, - responseHeaders, - status, - delay, - ex - ); - LOG.debug("Will report result of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", - resultRequest.getRetStatus().name(), request.getMethod(), request.getURI().getPath(), status, delay); - consumerAPI.updateServiceCallResult(resultRequest); - - ResourceStat resourceStat = createInstanceResourceStat( - request.getURI().getHost(), - targetHost, - targetPort, - request.getURI(), - status, - delay, - ex - ); - circuitBreakAPI.report(resourceStat); - - if (ex != null) { - throw ex; - } - return response; - } - -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplate.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplate.java new file mode 100644 index 000000000..7881799b6 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplate.java @@ -0,0 +1,105 @@ +/* + * 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.rpc.enhancement.resttemplate; + +import java.io.IOException; +import java.util.Map; + +import com.tencent.cloud.common.constant.HeaderConstant; +import com.tencent.cloud.common.metadata.MetadataContextHolder; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; + +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; + +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION; +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY; +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST; +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.PRE; + +/** + * EnhancedRestTemplate. + * + * @author sean yu + */ +public class EnhancedRestTemplate implements ClientHttpRequestInterceptor { + + private final EnhancedPluginRunner pluginRunner; + + public EnhancedRestTemplate(EnhancedPluginRunner pluginRunner) { + this.pluginRunner = pluginRunner; + } + + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { + + EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext(); + + EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder() + .httpHeaders(request.getHeaders()) + .httpMethod(request.getMethod()) + .url(request.getURI()) + .build(); + enhancedPluginContext.setRequest(enhancedRequestContext); + + // Run pre enhanced plugins. + pluginRunner.run(PRE, enhancedPluginContext); + long startMillis = System.currentTimeMillis(); + try { + ClientHttpResponse response = execution.execute(request, body); + enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); + + EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder() + .httpStatus(response.getRawStatusCode()) + .httpHeaders(response.getHeaders()) + .build(); + enhancedPluginContext.setResponse(enhancedResponseContext); + + Map loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata(); + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); + serviceInstance.setServiceId(request.getURI().getHost()); + serviceInstance.setHost(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST)); + if (loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT) != null) { + serviceInstance.setPort(Integer.parseInt(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT))); + } + enhancedPluginContext.setServiceInstance(serviceInstance); + + // Run post enhanced plugins. + pluginRunner.run(POST, enhancedPluginContext); + return response; + } + catch (IOException e) { + enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); + enhancedPluginContext.setThrowable(e); + // Run exception enhanced plugins. + pluginRunner.run(EXCEPTION, enhancedPluginContext); + throw e; + } + finally { + // Run finally enhanced plugins. + pluginRunner.run(FINALLY, enhancedPluginContext); + } + } + +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilter.java new file mode 100644 index 000000000..3241111aa --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilter.java @@ -0,0 +1,111 @@ +/* + * 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.rpc.enhancement.scg; + +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; +import reactor.core.publisher.Mono; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.loadbalancer.Response; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.web.server.ServerWebExchange; + +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION; +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY; +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST; +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.PRE; +import static org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter.ROUTE_TO_URL_FILTER_ORDER; +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_LOADBALANCER_RESPONSE_ATTR; + +/** + * EnhancedGatewayGlobalFilter. + * + * @author sean yu + */ +public class EnhancedGatewayGlobalFilter implements GlobalFilter, Ordered { + + private final EnhancedPluginRunner pluginRunner; + + public EnhancedGatewayGlobalFilter(EnhancedPluginRunner pluginRunner) { + this.pluginRunner = pluginRunner; + } + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext(); + + EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder() + .httpHeaders(exchange.getRequest().getHeaders()) + .httpMethod(exchange.getRequest().getMethod()) + .url(exchange.getRequest().getURI()) + .build(); + enhancedPluginContext.setRequest(enhancedRequestContext); + + // Run pre enhanced plugins. + pluginRunner.run(PRE, enhancedPluginContext); + + long startTime = System.currentTimeMillis(); + return chain.filter(exchange) + .doOnSuccess(v -> { + enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime); + + EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder() + .httpStatus(exchange.getResponse().getRawStatusCode()) + .httpHeaders(exchange.getResponse().getHeaders()) + .build(); + enhancedPluginContext.setResponse(enhancedResponseContext); + + Response serviceInstanceResponse = exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR); + if (serviceInstanceResponse != null && serviceInstanceResponse.hasServer()) { + ServiceInstance instance = serviceInstanceResponse.getServer(); + enhancedPluginContext.setServiceInstance(instance); + } + + // Run post enhanced plugins. + pluginRunner.run(POST, enhancedPluginContext); + }) + .doOnError(t -> { + enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime); + + enhancedPluginContext.setThrowable(t); + + Response serviceInstanceResponse = exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR); + if (serviceInstanceResponse != null && serviceInstanceResponse.hasServer()) { + ServiceInstance instance = serviceInstanceResponse.getServer(); + enhancedPluginContext.setServiceInstance(instance); + } + + // Run exception enhanced plugins. + pluginRunner.run(EXCEPTION, enhancedPluginContext); + }) + .doFinally(v -> { + // Run finally enhanced plugins. + pluginRunner.run(FINALLY, enhancedPluginContext); + }); + } + + @Override + public int getOrder() { + return ROUTE_TO_URL_FILTER_ORDER + 1; + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedPolarisGatewayReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedPolarisGatewayReporter.java deleted file mode 100644 index 41c85ebfc..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedPolarisGatewayReporter.java +++ /dev/null @@ -1,129 +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.rpc.enhancement.scg; - -import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat; -import com.tencent.polaris.api.rpc.ServiceCallResult; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; -import com.tencent.polaris.client.api.SDKContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.gateway.filter.GatewayFilterChain; -import org.springframework.cloud.gateway.filter.GlobalFilter; -import org.springframework.core.Ordered; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.web.server.ServerWebExchange; - -import static org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter.ROUTE_TO_URL_FILTER_ORDER; -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_LOADBALANCER_RESPONSE_ATTR; - -/** - * EnhancedPolarisGatewayReporter. - * - * @author sean yu - */ -public class EnhancedPolarisGatewayReporter extends AbstractPolarisReporterAdapter implements GlobalFilter, Ordered { - - private static final Logger LOG = LoggerFactory.getLogger(EnhancedPolarisGatewayReporter.class); - - private final ConsumerAPI consumerAPI; - - private final CircuitBreakAPI circuitBreakAPI; - - /** - * Constructor With {@link RpcEnhancementReporterProperties} . - * - * @param reportProperties instance of {@link RpcEnhancementReporterProperties}. - */ - public EnhancedPolarisGatewayReporter(RpcEnhancementReporterProperties reportProperties, - SDKContext context, - ConsumerAPI consumerAPI, - CircuitBreakAPI circuitBreakAPI) { - super(reportProperties, context); - this.consumerAPI = consumerAPI; - this.circuitBreakAPI = circuitBreakAPI; - } - - @Override - public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { - if (!reportProperties.isEnabled()) { - return chain.filter(exchange); - } - long startTime = System.currentTimeMillis(); - return chain.filter(exchange) - .doOnSuccess(v -> instrumentResponse(exchange, null, startTime)) - .doOnError(t -> instrumentResponse(exchange, t, startTime)); - } - - private void instrumentResponse(ServerWebExchange exchange, Throwable t, long startTime) { - ServerHttpResponse response = exchange.getResponse(); - ServerHttpRequest request = exchange.getRequest(); - - long delay = System.currentTimeMillis() - startTime; - String serviceId = null; - String targetHost = null; - Integer targetPort = null; - - Response serviceInstanceResponse = exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR); - if (serviceInstanceResponse != null && serviceInstanceResponse.hasServer()) { - ServiceInstance instance = serviceInstanceResponse.getServer(); - serviceId = instance.getServiceId(); - targetHost = instance.getHost(); - targetPort = instance.getPort(); - } - - ServiceCallResult resultRequest = createServiceCallResult( - serviceId, - targetHost, - targetPort, - request.getURI(), - request.getHeaders(), - response.getHeaders(), - response.getRawStatusCode(), - delay, - t - ); - LOG.debug("Will report result of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", - resultRequest.getRetStatus().name(), request.getMethod(), request.getURI().getPath(), response.getRawStatusCode(), delay); - consumerAPI.updateServiceCallResult(resultRequest); - - ResourceStat resourceStat = createInstanceResourceStat( - serviceId, - targetHost, - targetPort, - request.getURI(), - response.getRawStatusCode(), - delay, - t - ); - circuitBreakAPI.report(resourceStat); - } - - @Override - public int getOrder() { - return ROUTE_TO_URL_FILTER_ORDER + 1; - } -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporter.java index c78348916..5cd19e9c7 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporter.java @@ -21,87 +21,84 @@ import java.util.Map; import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.metadata.MetadataContextHolder; -import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter; -import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat; -import com.tencent.polaris.api.rpc.ServiceCallResult; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; -import com.tencent.polaris.client.api.SDKContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; import reactor.core.publisher.Mono; -import org.springframework.http.HttpHeaders; +import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.ExchangeFilterFunction; import org.springframework.web.reactive.function.client.ExchangeFunction; +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION; +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY; +import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST; + /** * EnhancedWebClientReporter. * * @author sean yu */ -public class EnhancedWebClientReporter extends AbstractPolarisReporterAdapter implements ExchangeFilterFunction { - private static final Logger LOG = LoggerFactory.getLogger(EnhancedWebClientReporter.class); - private final ConsumerAPI consumerAPI; - - private final CircuitBreakAPI circuitBreakAPI; - - public EnhancedWebClientReporter(RpcEnhancementReporterProperties reportProperties, - SDKContext context, - ConsumerAPI consumerAPI, - CircuitBreakAPI circuitBreakAPI) { - super(reportProperties, context); - this.consumerAPI = consumerAPI; - this.circuitBreakAPI = circuitBreakAPI; +public class EnhancedWebClientReporter implements ExchangeFilterFunction { + private final EnhancedPluginRunner pluginRunner; + + public EnhancedWebClientReporter(EnhancedPluginRunner pluginRunner) { + this.pluginRunner = pluginRunner; } @Override public Mono filter(ClientRequest request, ExchangeFunction next) { - if (!reportProperties.isEnabled()) { - return next.exchange(request); - } + EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext(); + + EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder() + .httpHeaders(request.headers()) + .httpMethod(request.method()) + .url(request.url()) + .build(); + enhancedPluginContext.setRequest(enhancedRequestContext); + long startTime = System.currentTimeMillis(); return next.exchange(request) - .doOnSuccess(response -> instrumentResponse(request, response, null, startTime)) - .doOnError(t -> instrumentResponse(request, null, t, startTime)); - } + .doOnSuccess(response -> { + enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime); + + EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder() + .httpStatus(response.rawStatusCode()) + .httpHeaders(response.headers().asHttpHeaders()) + .build(); + enhancedPluginContext.setResponse(enhancedResponseContext); + + Map loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata(); + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); + serviceInstance.setServiceId(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID)); + serviceInstance.setHost(request.url().getHost()); + serviceInstance.setPort(request.url().getPort()); + enhancedPluginContext.setServiceInstance(serviceInstance); + + // Run post enhanced plugins. + pluginRunner.run(POST, enhancedPluginContext); + }) + .doOnError(t -> { + enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime); + + enhancedPluginContext.setThrowable(t); + + Map loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata(); + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); + serviceInstance.setServiceId(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID)); + serviceInstance.setHost(request.url().getHost()); + serviceInstance.setPort(request.url().getPort()); + enhancedPluginContext.setServiceInstance(serviceInstance); - private void instrumentResponse(ClientRequest request, ClientResponse response, Throwable t, long startTime) { - Map loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata(); - String serviceId = loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID); - long delay = System.currentTimeMillis() - startTime; - - HttpHeaders requestHeaders = request.headers(); - HttpHeaders responseHeaders = null; - Integer status = null; - if (response != null) { - responseHeaders = response.headers().asHttpHeaders(); - status = response.rawStatusCode(); - } - - ServiceCallResult resultRequest = createServiceCallResult( - serviceId, - request.url(), - requestHeaders, - responseHeaders, - status, - delay, - t - ); - LOG.debug("Will report result of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", - resultRequest.getRetStatus().name(), request.method().name(), request.url().getPath(), status, delay); - consumerAPI.updateServiceCallResult(resultRequest); - - ResourceStat resourceStat = createInstanceResourceStat( - serviceId, - request.url(), - status, - delay, - t - ); - circuitBreakAPI.report(resourceStat); + // Run exception enhanced plugins. + pluginRunner.run(EXCEPTION, enhancedPluginContext); + }) + .doFinally(v -> { + // Run finally enhanced plugins. + pluginRunner.run(FINALLY, enhancedPluginContext); + }); } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java index 82557e425..825da246f 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java @@ -106,6 +106,8 @@ public class AbstractPolarisReporterAdapterTest { serviceCallResult = adapter.createServiceCallResult( "test", + null, + null, new URI("http://0.0.0.0/"), requestHeaders, new HttpHeaders(), @@ -117,6 +119,8 @@ public class AbstractPolarisReporterAdapterTest { serviceCallResult = adapter.createServiceCallResult( "test", + null, + null, new URI("http://0.0.0.0/"), requestHeaders, new HttpHeaders(), @@ -128,6 +132,8 @@ public class AbstractPolarisReporterAdapterTest { serviceCallResult = adapter.createServiceCallResult( "test", + null, + null, new URI("http://0.0.0.0/"), requestHeaders, null, @@ -161,6 +167,8 @@ public class AbstractPolarisReporterAdapterTest { ResourceStat resourceStat; resourceStat = adapter.createInstanceResourceStat("test", + null, + null, new URI("http://0.0.0.0/"), 200, 0, @@ -169,6 +177,8 @@ public class AbstractPolarisReporterAdapterTest { assertThat(resourceStat.getRetStatus()).isEqualTo(RetStatus.RetSuccess); resourceStat = adapter.createInstanceResourceStat("test", + null, + null, new URI("http://0.0.0.0/"), null, 0, diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java index 30993b9f2..96825318f 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfigurationTest.java @@ -19,10 +19,10 @@ package com.tencent.cloud.rpc.enhancement.config; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignBeanPostProcessor; -import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignPluginRunner; -import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.ExceptionPolarisReporter; -import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.SuccessPolarisReporter; -import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedPolarisRestTemplateReporter; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter; +import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter; +import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplate; import com.tencent.polaris.api.core.ConsumerAPI; import org.junit.jupiter.api.Test; @@ -56,11 +56,11 @@ public class RpcEnhancementAutoConfigurationTest { public void testDefaultInitialization() { this.contextRunner.run(context -> { assertThat(context).hasSingleBean(ConsumerAPI.class); - assertThat(context).hasSingleBean(EnhancedFeignPluginRunner.class); + assertThat(context).hasSingleBean(EnhancedPluginRunner.class); assertThat(context).hasSingleBean(EnhancedFeignBeanPostProcessor.class); assertThat(context).hasSingleBean(SuccessPolarisReporter.class); assertThat(context).hasSingleBean(ExceptionPolarisReporter.class); - assertThat(context).hasSingleBean(EnhancedPolarisRestTemplateReporter.class); + assertThat(context).hasSingleBean(EnhancedRestTemplate.class); assertThat(context).hasSingleBean(RestTemplate.class); }); } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterPropertiesTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterPropertiesTest.java index e3483decc..6ed9d8857 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterPropertiesTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementReporterPropertiesTest.java @@ -40,7 +40,8 @@ import static org.springframework.http.HttpStatus.Series.SERVER_ERROR; @ExtendWith(SpringExtension.class) @SpringBootTest(classes = RpcEnhancementReporterPropertiesTest.TestApplication.class, properties = { "spring.application.name=test", - "spring.cloud.gateway.enabled=false" + "spring.cloud.gateway.enabled=false", + "spring.cloud.tencent.rpc-enhancement.reporter=true" }) @ActiveProfiles("test") public class RpcEnhancementReporterPropertiesTest { @@ -58,6 +59,7 @@ public class RpcEnhancementReporterPropertiesTest { assertThat(rpcEnhancementReporterProperties.getStatuses()).isNotEmpty(); assertThat(rpcEnhancementReporterProperties.getStatuses().get(0)).isEqualTo(MULTIPLE_CHOICES); assertThat(rpcEnhancementReporterProperties.getStatuses().get(1)).isEqualTo(MOVED_PERMANENTLY); + assertThat(rpcEnhancementReporterProperties.isEnabled()).isEqualTo(true); } @SpringBootApplication diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java index e1c8eacf6..2ff9ff909 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/EnhancedFeignClientTest.java @@ -22,9 +22,10 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; +import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; import feign.Client; import feign.Request; import feign.RequestTemplate; @@ -72,9 +73,9 @@ public class EnhancedFeignClientTest { fail("Exception encountered.", e); } - List enhancedFeignPlugins = getMockEnhancedFeignPlugins(); + List enhancedPlugins = getMockEnhancedFeignPlugins(); try { - new EnhancedFeignClient(mock(Client.class), new DefaultEnhancedFeignPluginRunner(enhancedFeignPlugins)); + new EnhancedFeignClient(mock(Client.class), new DefaultEnhancedPluginRunner(enhancedPlugins)); } catch (Throwable e) { fail("Exception encountered.", e); @@ -103,7 +104,7 @@ public class EnhancedFeignClientTest { RequestTemplate requestTemplate = new RequestTemplate(); requestTemplate.feignTarget(target); - EnhancedFeignClient polarisFeignClient = new EnhancedFeignClient(delegate, new DefaultEnhancedFeignPluginRunner(getMockEnhancedFeignPlugins())); + EnhancedFeignClient polarisFeignClient = new EnhancedFeignClient(delegate, new DefaultEnhancedPluginRunner(getMockEnhancedFeignPlugins())); // 200 Response response = polarisFeignClient.execute(Request.create(Request.HttpMethod.GET, "http://localhost:8080/test", @@ -127,22 +128,22 @@ public class EnhancedFeignClientTest { } } - private List getMockEnhancedFeignPlugins() { - List enhancedFeignPlugins = new ArrayList<>(); + private List getMockEnhancedFeignPlugins() { + List enhancedPlugins = new ArrayList<>(); - enhancedFeignPlugins.add(new EnhancedFeignPlugin() { + enhancedPlugins.add(new EnhancedPlugin() { @Override - public EnhancedFeignPluginType getType() { - return EnhancedFeignPluginType.PRE; + public EnhancedPluginType getType() { + return EnhancedPluginType.PRE; } @Override - public void run(EnhancedFeignContext context) { + public void run(EnhancedPluginContext context) { } @Override - public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { + public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) { } @@ -152,19 +153,19 @@ public class EnhancedFeignClientTest { } }); - enhancedFeignPlugins.add(new EnhancedFeignPlugin() { + enhancedPlugins.add(new EnhancedPlugin() { @Override - public EnhancedFeignPluginType getType() { - return EnhancedFeignPluginType.POST; + public EnhancedPluginType getType() { + return EnhancedPluginType.POST; } @Override - public void run(EnhancedFeignContext context) { + public void run(EnhancedPluginContext context) { } @Override - public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { + public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) { } @@ -174,19 +175,19 @@ public class EnhancedFeignClientTest { } }); - enhancedFeignPlugins.add(new EnhancedFeignPlugin() { + enhancedPlugins.add(new EnhancedPlugin() { @Override - public EnhancedFeignPluginType getType() { - return EnhancedFeignPluginType.EXCEPTION; + public EnhancedPluginType getType() { + return EnhancedPluginType.EXCEPTION; } @Override - public void run(EnhancedFeignContext context) { + public void run(EnhancedPluginContext context) { } @Override - public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { + public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) { } @@ -196,19 +197,19 @@ public class EnhancedFeignClientTest { } }); - enhancedFeignPlugins.add(new EnhancedFeignPlugin() { + enhancedPlugins.add(new EnhancedPlugin() { @Override - public EnhancedFeignPluginType getType() { - return EnhancedFeignPluginType.FINALLY; + public EnhancedPluginType getType() { + return EnhancedPluginType.FINALLY; } @Override - public void run(EnhancedFeignContext context) { + public void run(EnhancedPluginContext context) { } @Override - public void handlerThrowable(EnhancedFeignContext context, Throwable throwable) { + public void handlerThrowable(EnhancedPluginContext context, Throwable throwable) { } @@ -218,7 +219,7 @@ public class EnhancedFeignClientTest { } }); - return enhancedFeignPlugins; + return enhancedPlugins; } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContextTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContextTest.java deleted file mode 100644 index 0143fc844..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/EnhancedFeignContextTest.java +++ /dev/null @@ -1,46 +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.rpc.enhancement.feign.plugin; - -import feign.Request; -import feign.Response; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Test for {@link EnhancedFeignContext}. - * - * @author Haotian Zhang - */ -public class EnhancedFeignContextTest { - - @Test - public void testGetAndSet() { - EnhancedFeignContext enhancedFeignContext = new EnhancedFeignContext(); - enhancedFeignContext.setRequest(mock(Request.class)); - enhancedFeignContext.setOptions(mock(Request.Options.class)); - enhancedFeignContext.setResponse(mock(Response.class)); - enhancedFeignContext.setException(mock(Exception.class)); - assertThat(enhancedFeignContext.getRequest()).isNotNull(); - assertThat(enhancedFeignContext.getOptions()).isNotNull(); - assertThat(enhancedFeignContext.getResponse()).isNotNull(); - assertThat(enhancedFeignContext.getException()).isNotNull(); - } -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContextTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContextTest.java new file mode 100644 index 000000000..a516483f1 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContextTest.java @@ -0,0 +1,134 @@ +/* + * 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.rpc.enhancement.plugin; + +import java.net.URI; +import java.util.Arrays; + +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; +import com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter; +import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.client.api.SDKContext; +import org.junit.jupiter.api.AfterAll; +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 org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; + +/** + * Test for {@link EnhancedPluginContext}. + * + * @author Haotian Zhang + */ +@ExtendWith(MockitoExtension.class) +public class EnhancedPluginContextTest { + + private static MockedStatic mockedApplicationContextAwareUtils; + @Mock + private RpcEnhancementReporterProperties reporterProperties; + @Mock + private SDKContext sdkContext; + @Mock + private ConsumerAPI consumerAPI; + + @BeforeAll + static void beforeAll() { + mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn("unit-test"); + } + + @AfterAll + static void afterAll() { + mockedApplicationContextAwareUtils.close(); + } + + @BeforeEach + void setUp() { + MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; + MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; + } + + @Test + public void testGetAndSet() throws Throwable { + EnhancedRequestContext requestContext = new EnhancedRequestContext(); + requestContext.setHttpHeaders(new HttpHeaders()); + requestContext.setUrl(new URI("/")); + requestContext.setHttpMethod(HttpMethod.GET); + + EnhancedRequestContext requestContext1 = EnhancedRequestContext.builder() + .httpHeaders(requestContext.getHttpHeaders()) + .url(requestContext.getUrl()) + .httpMethod(requestContext.getHttpMethod()) + .build(); + assertThat(requestContext1.getUrl()).isEqualTo(requestContext.getUrl()); + + EnhancedResponseContext responseContext = new EnhancedResponseContext(); + responseContext.setHttpStatus(200); + responseContext.setHttpHeaders(new HttpHeaders()); + + EnhancedResponseContext responseContext1 = EnhancedResponseContext.builder() + .httpStatus(responseContext.getHttpStatus()) + .httpHeaders(responseContext.getHttpHeaders()) + .build(); + assertThat(responseContext1.getHttpStatus()).isEqualTo(responseContext.getHttpStatus()); + + EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext(); + enhancedPluginContext.setRequest(requestContext); + enhancedPluginContext.setResponse(responseContext); + enhancedPluginContext.setServiceInstance(new DefaultServiceInstance()); + enhancedPluginContext.setThrowable(mock(Exception.class)); + enhancedPluginContext.setDelay(0); + assertThat(enhancedPluginContext.getRequest()).isNotNull(); + assertThat(enhancedPluginContext.getResponse()).isNotNull(); + assertThat(enhancedPluginContext.getServiceInstance()).isNotNull(); + assertThat(enhancedPluginContext.getThrowable()).isNotNull(); + assertThat(enhancedPluginContext.getDelay()).isNotNull(); + + EnhancedPlugin enhancedPlugin = new SuccessPolarisReporter(reporterProperties, sdkContext, consumerAPI); + EnhancedPlugin enhancedPlugin1 = new ExceptionPolarisReporter(reporterProperties, sdkContext, consumerAPI); + EnhancedPluginRunner enhancedPluginRunner = new DefaultEnhancedPluginRunner(Arrays.asList(enhancedPlugin, enhancedPlugin1)); + enhancedPluginRunner.run(EnhancedPluginType.POST, enhancedPluginContext); + + EnhancedPlugin enhancedPlugin2 = mock(EnhancedPlugin.class); + doThrow(new RuntimeException()).when(enhancedPlugin2).run(any()); + doReturn(EnhancedPluginType.POST).when(enhancedPlugin2).getType(); + enhancedPluginRunner = new DefaultEnhancedPluginRunner(Arrays.asList(enhancedPlugin2)); + enhancedPluginRunner.run(EnhancedPluginType.POST, enhancedPluginContext); + } +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java similarity index 74% rename from spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java index b89bbf7ee..21c61ef92 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/ExceptionPolarisReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java @@ -15,25 +15,19 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.rpc.enhancement.feign.plugin.reporter; +package com.tencent.cloud.rpc.enhancement.plugin; -import java.util.HashMap; +import java.net.URI; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; +import com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter; import com.tencent.polaris.api.config.Configuration; import com.tencent.polaris.api.config.global.APIConfig; import com.tencent.polaris.api.config.global.GlobalConfig; import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; import com.tencent.polaris.client.api.SDKContext; -import feign.Request; -import feign.RequestTemplate; -import feign.Response; -import feign.Target; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -45,6 +39,10 @@ import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; + import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; import static org.assertj.core.api.Assertions.assertThat; @@ -67,12 +65,10 @@ public class ExceptionPolarisReporterTest { private RpcEnhancementReporterProperties reporterProperties; @Mock private SDKContext sdkContext; - @Mock - private ConsumerAPI consumerAPI; - @Mock - private CircuitBreakAPI circuitBreakAPI; @InjectMocks private ExceptionPolarisReporter exceptionPolarisReporter; + @Mock + private ConsumerAPI consumerAPI; @BeforeAll static void beforeAll() { @@ -99,20 +95,17 @@ public class ExceptionPolarisReporterTest { @Test public void testType() { - assertThat(exceptionPolarisReporter.getType()).isEqualTo(EnhancedFeignPluginType.EXCEPTION); + assertThat(exceptionPolarisReporter.getType()).isEqualTo(EnhancedPluginType.EXCEPTION); } @Test public void testRun() { - EnhancedFeignContext context = mock(EnhancedFeignContext.class); + EnhancedPluginContext context = mock(EnhancedPluginContext.class); // test not report exceptionPolarisReporter.run(context); verify(context, times(0)).getRequest(); doReturn(true).when(reporterProperties).isEnabled(); - // mock target - Target target = mock(Target.class); - doReturn(SERVICE_PROVIDER).when(target).name(); APIConfig apiConfig = mock(APIConfig.class); doReturn("0.0.0.0").when(apiConfig).getBindIP(); @@ -125,29 +118,37 @@ public class ExceptionPolarisReporterTest { doReturn(configuration).when(sdkContext).getConfig(); - // mock RequestTemplate.class - RequestTemplate requestTemplate = new RequestTemplate(); - requestTemplate.feignTarget(target); - - EnhancedFeignContext feignContext = new EnhancedFeignContext(); - Request request = Request.create(Request.HttpMethod.GET, "http://0.0.0.0/", new HashMap<>(), null, null, requestTemplate); - Response response = Response.builder() - .request(request) + EnhancedPluginContext pluginContext = new EnhancedPluginContext(); + EnhancedRequestContext request = EnhancedRequestContext.builder() + .httpMethod(HttpMethod.GET) + .url(URI.create("http://0.0.0.0/")) + .httpHeaders(new HttpHeaders()) + .build(); + EnhancedResponseContext response = EnhancedResponseContext.builder() + .httpStatus(200) .build(); - feignContext.setRequest(request); - feignContext.setResponse(response); - exceptionPolarisReporter.run(feignContext); + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); + serviceInstance.setServiceId(SERVICE_PROVIDER); + + pluginContext.setRequest(request); + pluginContext.setResponse(response); + pluginContext.setServiceInstance(serviceInstance); + pluginContext.setThrowable(new RuntimeException()); + + exceptionPolarisReporter.run(pluginContext); exceptionPolarisReporter.getOrder(); + exceptionPolarisReporter.getName(); + exceptionPolarisReporter.getType(); } @Test public void testHandlerThrowable() { // mock request - Request request = mock(Request.class); + EnhancedRequestContext request = mock(EnhancedRequestContext.class); // mock response - Response response = mock(Response.class); + EnhancedResponseContext response = mock(EnhancedResponseContext.class); - EnhancedFeignContext context = new EnhancedFeignContext(); + EnhancedPluginContext context = new EnhancedPluginContext(); context.setRequest(request); context.setResponse(response); exceptionPolarisReporter.handlerThrowable(context, new RuntimeException("Mock exception.")); diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java similarity index 75% rename from spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java index 634b8a118..9af4ca019 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/feign/plugin/reporter/SuccessPolarisReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java @@ -15,25 +15,19 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.rpc.enhancement.feign.plugin.reporter; +package com.tencent.cloud.rpc.enhancement.plugin; -import java.util.HashMap; +import java.net.URI; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignContext; -import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPluginType; +import com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter; import com.tencent.polaris.api.config.Configuration; import com.tencent.polaris.api.config.global.APIConfig; import com.tencent.polaris.api.config.global.GlobalConfig; import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; import com.tencent.polaris.client.api.SDKContext; -import feign.Request; -import feign.RequestTemplate; -import feign.Response; -import feign.Target; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -45,6 +39,9 @@ import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.http.HttpMethod; + import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; import static org.assertj.core.api.Assertions.assertThat; @@ -65,13 +62,11 @@ public class SuccessPolarisReporterTest { @Mock private SDKContext sdkContext; @Mock - private ConsumerAPI consumerAPI; - @Mock - private CircuitBreakAPI circuitBreakAPI; - @Mock private RpcEnhancementReporterProperties reporterProperties; @InjectMocks private SuccessPolarisReporter successPolarisReporter; + @Mock + private ConsumerAPI consumerAPI; @BeforeAll static void beforeAll() { @@ -98,22 +93,18 @@ public class SuccessPolarisReporterTest { @Test public void testType() { - assertThat(successPolarisReporter.getType()).isEqualTo(EnhancedFeignPluginType.POST); + assertThat(successPolarisReporter.getType()).isEqualTo(EnhancedPluginType.POST); } @Test public void testRun() { - EnhancedFeignContext context = mock(EnhancedFeignContext.class); + EnhancedPluginContext context = mock(EnhancedPluginContext.class); // test not report successPolarisReporter.run(context); verify(context, times(0)).getRequest(); doReturn(true).when(reporterProperties).isEnabled(); - // mock target - Target target = mock(Target.class); - doReturn(SERVICE_PROVIDER).when(target).name(); - APIConfig apiConfig = mock(APIConfig.class); doReturn("0.0.0.0").when(apiConfig).getBindIP(); @@ -125,29 +116,35 @@ public class SuccessPolarisReporterTest { doReturn(configuration).when(sdkContext).getConfig(); - // mock RequestTemplate.class - RequestTemplate requestTemplate = new RequestTemplate(); - requestTemplate.feignTarget(target); - - EnhancedFeignContext feignContext = new EnhancedFeignContext(); - Request request = Request.create(Request.HttpMethod.GET, "http://0.0.0.0/", new HashMap<>(), null, null, requestTemplate); - Response response = Response.builder() - .request(request) + EnhancedPluginContext pluginContext = new EnhancedPluginContext(); + EnhancedRequestContext request = EnhancedRequestContext.builder() + .httpMethod(HttpMethod.GET) + .url(URI.create("http://0.0.0.0/")) + .build(); + EnhancedResponseContext response = EnhancedResponseContext.builder() + .httpStatus(200) .build(); - feignContext.setRequest(request); - feignContext.setResponse(response); - successPolarisReporter.run(feignContext); + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); + serviceInstance.setServiceId(SERVICE_PROVIDER); + + pluginContext.setRequest(request); + pluginContext.setResponse(response); + pluginContext.setServiceInstance(serviceInstance); + + successPolarisReporter.run(pluginContext); successPolarisReporter.getOrder(); + successPolarisReporter.getName(); + successPolarisReporter.getType(); } @Test public void testHandlerThrowable() { // mock request - Request request = mock(Request.class); + EnhancedRequestContext request = mock(EnhancedRequestContext.class); // mock response - Response response = mock(Response.class); + EnhancedResponseContext response = mock(EnhancedResponseContext.class); - EnhancedFeignContext context = new EnhancedFeignContext(); + EnhancedPluginContext context = new EnhancedPluginContext(); context.setRequest(request); context.setResponse(response); successPolarisReporter.handlerThrowable(context, new RuntimeException("Mock exception.")); diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateTest.java similarity index 83% rename from spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporterTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateTest.java index c91552df3..7b42a32e0 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateTest.java @@ -21,17 +21,14 @@ import java.io.IOException; import java.net.SocketTimeoutException; import java.net.URI; import java.net.URISyntaxException; +import java.util.ArrayList; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.polaris.api.config.Configuration; -import com.tencent.polaris.api.config.global.APIConfig; -import com.tencent.polaris.api.config.global.GlobalConfig; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; +import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner; import com.tencent.polaris.client.api.SDKContext; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -60,7 +57,7 @@ import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; @ExtendWith(MockitoExtension.class) -public class EnhancedPolarisRestTemplateReporterTest { +public class EnhancedRestTemplateTest { private static MockedStatic mockedApplicationContextAwareUtils; @Mock @@ -68,10 +65,6 @@ public class EnhancedPolarisRestTemplateReporterTest { @Mock private SDKContext sdkContext; @Mock - private ConsumerAPI consumerAPI; - @Mock - private CircuitBreakAPI circuitBreakAPI; - @Mock private ClientHttpRequestExecution mockClientHttpRequestExecution; @Mock private ClientHttpResponse mockClientHttpResponse; @@ -107,17 +100,6 @@ public class EnhancedPolarisRestTemplateReporterTest { @Test public void testRun() throws IOException, URISyntaxException { - APIConfig apiConfig = mock(APIConfig.class); - doReturn("0.0.0.0").when(apiConfig).getBindIP(); - - GlobalConfig globalConfig = mock(GlobalConfig.class); - doReturn(apiConfig).when(globalConfig).getAPI(); - - Configuration configuration = mock(Configuration.class); - doReturn(globalConfig).when(configuration).getGlobal(); - - doReturn(configuration).when(sdkContext).getConfig(); - ClientHttpResponse actualResult; final byte[] inputBody = null; @@ -127,11 +109,10 @@ public class EnhancedPolarisRestTemplateReporterTest { doReturn(mockHttpHeaders).when(mockHttpRequest).getHeaders(); doReturn(mockClientHttpResponse).when(mockClientHttpRequestExecution).execute(mockHttpRequest, inputBody); - EnhancedPolarisRestTemplateReporter reporter = new EnhancedPolarisRestTemplateReporter(reporterProperties, sdkContext, consumerAPI, circuitBreakAPI); + EnhancedRestTemplate reporter = new EnhancedRestTemplate(new DefaultEnhancedPluginRunner(new ArrayList<>())); actualResult = reporter.intercept(mockHttpRequest, inputBody, mockClientHttpRequestExecution); assertThat(actualResult).isEqualTo(mockClientHttpResponse); - doReturn(true).when(reporterProperties).isEnabled(); actualResult = reporter.intercept(mockHttpRequest, inputBody, mockClientHttpRequestExecution); assertThat(actualResult).isEqualTo(mockClientHttpResponse); diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedPolarisGatewayReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java similarity index 80% rename from spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedPolarisGatewayReporterTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java index 96f9db122..6d5e8816d 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedPolarisGatewayReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java @@ -19,17 +19,14 @@ package com.tencent.cloud.rpc.enhancement.scg; import java.net.URI; import java.net.URISyntaxException; +import java.util.ArrayList; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.polaris.api.config.Configuration; -import com.tencent.polaris.api.config.global.APIConfig; -import com.tencent.polaris.api.config.global.GlobalConfig; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; +import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner; import com.tencent.polaris.client.api.SDKContext; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -54,13 +51,14 @@ import org.springframework.web.server.ServerWebExchange; import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_LOADBALANCER_RESPONSE_ATTR; @ExtendWith(MockitoExtension.class) -public class EnhancedPolarisGatewayReporterTest { +public class EnhancedGatewayGlobalFilterTest { private static MockedStatic mockedApplicationContextAwareUtils; @Mock @@ -68,10 +66,6 @@ public class EnhancedPolarisGatewayReporterTest { @Mock private SDKContext sdkContext; @Mock - private ConsumerAPI consumerAPI; - @Mock - private CircuitBreakAPI circuitBreakAPI; - @Mock ServerWebExchange exchange; @Mock GatewayFilterChain chain; @@ -106,16 +100,6 @@ public class EnhancedPolarisGatewayReporterTest { @Test public void testRun() throws URISyntaxException { - APIConfig apiConfig = mock(APIConfig.class); - doReturn("0.0.0.0").when(apiConfig).getBindIP(); - - GlobalConfig globalConfig = mock(GlobalConfig.class); - doReturn(apiConfig).when(globalConfig).getAPI(); - - Configuration configuration = mock(Configuration.class); - doReturn(globalConfig).when(configuration).getGlobal(); - - doReturn(configuration).when(sdkContext).getConfig(); doReturn(new URI("http://0.0.0.0/")).when(request).getURI(); doReturn(new HttpHeaders()).when(request).getHeaders(); @@ -124,9 +108,6 @@ public class EnhancedPolarisGatewayReporterTest { doReturn(Mono.empty()).when(chain).filter(exchange); ServiceInstance serviceInstance = mock(ServiceInstance.class); - doReturn("test").when(serviceInstance).getServiceId(); - doReturn("0.0.0.0").when(serviceInstance).getHost(); - doReturn(80).when(serviceInstance).getPort(); Response serviceInstanceResponse = new Response() { @Override public boolean hasServer() { @@ -142,14 +123,14 @@ public class EnhancedPolarisGatewayReporterTest { doReturn(request).when(exchange).getRequest(); doReturn(response).when(exchange).getResponse(); - EnhancedPolarisGatewayReporter reporter = new EnhancedPolarisGatewayReporter(reporterProperties, sdkContext, consumerAPI, circuitBreakAPI); + EnhancedGatewayGlobalFilter reporter = new EnhancedGatewayGlobalFilter(new DefaultEnhancedPluginRunner(new ArrayList<>())); reporter.getOrder(); reporter.filter(exchange, chain).block(); - doReturn(true).when(reporterProperties).isEnabled(); + doReturn(Mono.error(new RuntimeException())).when(chain).filter(exchange); - reporter.filter(exchange, chain).block(); + assertThatThrownBy(() -> reporter.filter(exchange, chain).block()).isInstanceOf(RuntimeException.class); } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java index fde7f5ce9..f8a4a673a 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java @@ -19,17 +19,14 @@ package com.tencent.cloud.rpc.enhancement.webclient; import java.net.URI; import java.net.URISyntaxException; +import java.util.ArrayList; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -import com.tencent.polaris.api.config.Configuration; -import com.tencent.polaris.api.config.global.APIConfig; -import com.tencent.polaris.api.config.global.GlobalConfig; -import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; +import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner; import com.tencent.polaris.client.api.SDKContext; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -52,6 +49,7 @@ import org.springframework.web.reactive.function.client.ExchangeFunction; import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; @@ -66,10 +64,6 @@ public class EnhancedWebClientReporterTest { @Mock private SDKContext sdkContext; @Mock - private ConsumerAPI consumerAPI; - @Mock - private CircuitBreakAPI circuitBreakAPI; - @Mock private ClientRequest clientRequest; @Mock private ExchangeFunction exchangeFunction; @@ -101,16 +95,6 @@ public class EnhancedWebClientReporterTest { } @Test public void testRun() throws URISyntaxException { - APIConfig apiConfig = mock(APIConfig.class); - doReturn("0.0.0.0").when(apiConfig).getBindIP(); - - GlobalConfig globalConfig = mock(GlobalConfig.class); - doReturn(apiConfig).when(globalConfig).getAPI(); - - Configuration configuration = mock(Configuration.class); - doReturn(globalConfig).when(configuration).getGlobal(); - - doReturn(configuration).when(sdkContext).getConfig(); doReturn(new URI("http://0.0.0.0/")).when(clientRequest).url(); doReturn(new HttpHeaders()).when(clientRequest).headers(); @@ -119,14 +103,18 @@ public class EnhancedWebClientReporterTest { doReturn(headers).when(clientResponse).headers(); doReturn(Mono.just(clientResponse)).when(exchangeFunction).exchange(any()); - EnhancedWebClientReporter reporter = new EnhancedWebClientReporter(reporterProperties, sdkContext, consumerAPI, circuitBreakAPI); + EnhancedWebClientReporter reporter = new EnhancedWebClientReporter(new DefaultEnhancedPluginRunner(new ArrayList<>())); ClientResponse clientResponse1 = reporter.filter(clientRequest, exchangeFunction).block(); assertThat(clientResponse1).isEqualTo(clientResponse); - doReturn(true).when(reporterProperties).isEnabled(); ClientResponse clientResponse2 = reporter.filter(clientRequest, exchangeFunction).block(); assertThat(clientResponse2).isEqualTo(clientResponse); + doReturn(Mono.error(new RuntimeException())).when(exchangeFunction).exchange(any()); + + assertThatThrownBy(() -> reporter.filter(clientRequest, exchangeFunction).block()).isInstanceOf(RuntimeException.class); + + } }