diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e209b66..3c168d44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,3 +5,4 @@ - feature: Enhance default configuration to support `application*.yaml` and `bootstrap*.yaml`. - feat:adapt for nacos instance. - Refactoring: Refactor Circuitbreaker ut. +- refactor:refactor rpc enhancement. diff --git a/pom.xml b/pom.xml index 233e8707..e3623701 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ - 1.12.0-Hoxton.SR12 + 1.12.0-Hoxton.SR12-SNAPSHOT 5.2.22.RELEASE 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 7dd7bf0b..94f5c00b 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 @@ -94,15 +94,15 @@ public class PolarisCircuitBreakerAutoConfiguration { @Bean @ConditionalOnMissingBean(SuccessCircuitBreakerReporter.class) public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties, - SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) { - return new SuccessCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI); + CircuitBreakAPI circuitBreakAPI) { + return new SuccessCircuitBreakerReporter(properties, circuitBreakAPI); } @Bean @ConditionalOnMissingBean(ExceptionCircuitBreakerReporter.class) public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties, - SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) { - return new ExceptionCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI); + CircuitBreakAPI circuitBreakAPI) { + return new ExceptionCircuitBreakerReporter(properties, circuitBreakAPI); } @Bean 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 f2f50921..fba34d25 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 @@ -64,15 +64,15 @@ public class ReactivePolarisCircuitBreakerAutoConfiguration { @Bean @ConditionalOnMissingBean(SuccessCircuitBreakerReporter.class) public SuccessCircuitBreakerReporter successCircuitBreakerReporter(RpcEnhancementReporterProperties properties, - SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) { - return new SuccessCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI); + CircuitBreakAPI circuitBreakAPI) { + return new SuccessCircuitBreakerReporter(properties, circuitBreakAPI); } @Bean @ConditionalOnMissingBean(ExceptionCircuitBreakerReporter.class) public ExceptionCircuitBreakerReporter exceptionCircuitBreakerReporter(RpcEnhancementReporterProperties properties, - SDKContext polarisContext, CircuitBreakAPI circuitBreakAPI) { - return new ExceptionCircuitBreakerReporter(properties, polarisContext, circuitBreakAPI); + CircuitBreakAPI circuitBreakAPI) { + return new ExceptionCircuitBreakerReporter(properties, circuitBreakAPI); } @Bean 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 index 47fd5098..293b8433 100644 --- 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 @@ -19,15 +19,14 @@ 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.PolarisEnhancedPluginUtils; 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; @@ -36,16 +35,22 @@ import org.springframework.cloud.client.ServiceInstance; import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER; -public class ExceptionCircuitBreakerReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { +/** + * ExceptionCircuitBreakerReporter. + * + * @author sean yu + */ +public class ExceptionCircuitBreakerReporter implements EnhancedPlugin { private static final Logger LOG = LoggerFactory.getLogger(ExceptionCircuitBreakerReporter.class); private final CircuitBreakAPI circuitBreakAPI; + private final RpcEnhancementReporterProperties reportProperties; + public ExceptionCircuitBreakerReporter(RpcEnhancementReporterProperties reportProperties, - SDKContext context, CircuitBreakAPI circuitBreakAPI) { - super(reportProperties, context); + this.reportProperties = reportProperties; this.circuitBreakAPI = circuitBreakAPI; } @@ -56,20 +61,20 @@ public class ExceptionCircuitBreakerReporter extends AbstractPolarisReporterAdap @Override public EnhancedPluginType getType() { - return EnhancedPluginType.EXCEPTION; + return EnhancedPluginType.Client.EXCEPTION; } @Override public void run(EnhancedPluginContext context) throws Throwable { - if (!super.reportProperties.isEnabled()) { + if (!this.reportProperties.isEnabled()) { return; } EnhancedRequestContext request = context.getRequest(); - ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()) + ServiceInstance serviceInstance = Optional.ofNullable(context.getTargetServiceInstance()) .orElse(new DefaultServiceInstance()); - ResourceStat resourceStat = createInstanceResourceStat( + ResourceStat resourceStat = PolarisEnhancedPluginUtils.createInstanceResourceStat( serviceInstance.getServiceId(), serviceInstance.getHost(), serviceInstance.getPort(), 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 index affc07d1..e11d7128 100644 --- 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 @@ -19,17 +19,16 @@ 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.PolarisEnhancedPluginUtils; 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; @@ -38,17 +37,22 @@ import org.springframework.cloud.client.ServiceInstance; import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.ClientPluginOrder.CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER; - -public class SuccessCircuitBreakerReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { +/** + * SuccessCircuitBreakerReporter. + * + * @author sean yu + */ +public class SuccessCircuitBreakerReporter implements EnhancedPlugin { private static final Logger LOG = LoggerFactory.getLogger(SuccessPolarisReporter.class); private final CircuitBreakAPI circuitBreakAPI; + private final RpcEnhancementReporterProperties reportProperties; + public SuccessCircuitBreakerReporter(RpcEnhancementReporterProperties reportProperties, - SDKContext context, CircuitBreakAPI circuitBreakAPI) { - super(reportProperties, context); + this.reportProperties = reportProperties; this.circuitBreakAPI = circuitBreakAPI; } @@ -59,20 +63,20 @@ public class SuccessCircuitBreakerReporter extends AbstractPolarisReporterAdapte @Override public EnhancedPluginType getType() { - return EnhancedPluginType.POST; + return EnhancedPluginType.Client.POST; } @Override public void run(EnhancedPluginContext context) throws Throwable { - if (!super.reportProperties.isEnabled()) { + if (!this.reportProperties.isEnabled()) { return; } EnhancedRequestContext request = context.getRequest(); EnhancedResponseContext response = context.getResponse(); - ServiceInstance serviceInstance = Optional.ofNullable(context.getServiceInstance()) + ServiceInstance serviceInstance = Optional.ofNullable(context.getTargetServiceInstance()) .orElse(new DefaultServiceInstance()); - ResourceStat resourceStat = createInstanceResourceStat( + ResourceStat resourceStat = PolarisEnhancedPluginUtils.createInstanceResourceStat( serviceInstance.getServiceId(), serviceInstance.getHost(), serviceInstance.getPort(), 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 index 53e38c9d..7be53b2f 100644 --- 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 @@ -95,7 +95,7 @@ public class ExceptionCircuitBreakerReporterTest { @Test public void testType() { - assertThat(exceptionCircuitBreakerReporter.getType()).isEqualTo(EnhancedPluginType.EXCEPTION); + assertThat(exceptionCircuitBreakerReporter.getType()).isEqualTo(EnhancedPluginType.Client.EXCEPTION); } @Test @@ -121,7 +121,7 @@ public class ExceptionCircuitBreakerReporterTest { pluginContext.setRequest(request); pluginContext.setResponse(response); - pluginContext.setServiceInstance(serviceInstance); + pluginContext.setTargetServiceInstance(serviceInstance); pluginContext.setThrowable(new RuntimeException()); exceptionCircuitBreakerReporter.run(pluginContext); 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 index 4dcd3d19..5d50a24c 100644 --- 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 @@ -40,6 +40,7 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.context.ApplicationContext; import org.springframework.http.HttpMethod; import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; @@ -74,6 +75,12 @@ public class SuccessCircuitBreakerReporterTest { mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) .thenReturn("unit-test"); + ApplicationContext applicationContext = mock(ApplicationContext.class); + RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class); + doReturn(reporterProperties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); } @AfterAll @@ -94,7 +101,7 @@ public class SuccessCircuitBreakerReporterTest { @Test public void testType() { - assertThat(successCircuitBreakerReporter.getType()).isEqualTo(EnhancedPluginType.POST); + assertThat(successCircuitBreakerReporter.getType()).isEqualTo(EnhancedPluginType.Client.POST); } @Test @@ -120,7 +127,7 @@ public class SuccessCircuitBreakerReporterTest { pluginContext.setRequest(request); pluginContext.setResponse(response); - pluginContext.setServiceInstance(serviceInstance); + pluginContext.setTargetServiceInstance(serviceInstance); successCircuitBreakerReporter.run(pluginContext); successCircuitBreakerReporter.getOrder(); diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java index ea480d40..3f83bfd4 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/PolarisDiscoveryProperties.java @@ -45,6 +45,11 @@ public class PolarisDiscoveryProperties { @Value("${spring.cloud.polaris.discovery.service:${spring.cloud.polaris.service:${spring.application.name:}}}") private String service; + /** + * Service instance id. + */ + private String instanceId; + /** * The polaris authentication token. */ @@ -96,6 +101,14 @@ public class PolarisDiscoveryProperties { */ private Long serviceListRefreshInterval = 60000L; + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + public String getNamespace() { return namespace; } @@ -204,6 +217,7 @@ public class PolarisDiscoveryProperties { return "PolarisDiscoveryProperties{" + "namespace='" + namespace + '\'' + ", service='" + service + '\'' + + ", instanceId='" + instanceId + '\'' + ", token='" + token + '\'' + ", weight=" + weight + ", version='" + version + '\'' + diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java index 77295688..d8c9b2f2 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java @@ -17,6 +17,9 @@ package com.tencent.cloud.polaris.registry; +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.polaris.api.pojo.ServiceKey; +import com.tencent.polaris.assembly.api.AssemblyAPI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,15 +35,21 @@ import org.springframework.util.StringUtils; */ public class PolarisAutoServiceRegistration extends AbstractAutoServiceRegistration { - private static final Logger LOG = LoggerFactory.getLogger(PolarisAutoServiceRegistration.class); + private static final Logger log = LoggerFactory.getLogger(PolarisAutoServiceRegistration.class); private final PolarisRegistration registration; - public PolarisAutoServiceRegistration(ServiceRegistry serviceRegistry, + private final AssemblyAPI assemblyAPI; + + public PolarisAutoServiceRegistration( + ServiceRegistry serviceRegistry, AutoServiceRegistrationProperties autoServiceRegistrationProperties, - PolarisRegistration registration) { + PolarisRegistration registration, + AssemblyAPI assemblyAPI + ) { super(serviceRegistry, autoServiceRegistrationProperties); this.registration = registration; + this.assemblyAPI = assemblyAPI; } @Override @@ -56,9 +65,12 @@ public class PolarisAutoServiceRegistration extends AbstractAutoServiceRegistrat @Override protected void register() { if (!this.registration.isRegisterEnabled()) { - LOG.debug("Registration disabled."); + log.debug("Registration disabled."); return; } + if (assemblyAPI != null) { + assemblyAPI.initService(new ServiceKey(MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE)); + } super.register(); } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java index e320ed53..843cae23 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java @@ -113,6 +113,7 @@ public class PolarisServiceRegistry implements ServiceRegistry> fragmentContexts; + private final Map loadbalancerMetadata; + + public MetadataContext() { this.fragmentContexts = new ConcurrentHashMap<>(); + this.loadbalancerMetadata = new ConcurrentHashMap<>(); } public Map getDisposableMetadata() { @@ -148,8 +147,8 @@ public class MetadataContext { return this.getFragmentContext(MetadataContext.FRAGMENT_RAW_TRANSHEADERS_KV); } - public Map getLoadbalancerMetadata() { - return this.getFragmentContext(FRAGMENT_LOAD_BALANCER); + public Map getLoadbalancerMetadata() { + return this.loadbalancerMetadata; } public void setTransitiveMetadata(Map transitiveMetadata) { @@ -172,8 +171,8 @@ public class MetadataContext { this.putContext(FRAGMENT_RAW_TRANSHEADERS, key, value); } - public void setLoadbalancer(String key, String value) { - this.putContext(FRAGMENT_LOAD_BALANCER, key, value); + public void setLoadbalancer(String key, Object value) { + this.loadbalancerMetadata.put(key, value); } public Map getFragmentContext(String fragment) { diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index 31b65766..b494a190 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -70,7 +70,7 @@ - 1.12.0-Hoxton.SR12 + 1.12.0-Hoxton.SR12-SNAPSHOT 1.13.0 diff --git a/spring-cloud-tencent-polaris-context/pom.xml b/spring-cloud-tencent-polaris-context/pom.xml index be6fbd90..62948c6c 100644 --- a/spring-cloud-tencent-polaris-context/pom.xml +++ b/spring-cloud-tencent-polaris-context/pom.xml @@ -110,6 +110,11 @@ com.tencent.polaris loadbalancer-ringhash + + + com.tencent.polaris + polaris-assembly-factory + diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java index 298d89fa..104a4e05 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfiguration.java @@ -27,6 +27,8 @@ import com.tencent.cloud.polaris.context.ServiceRuleManager; import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.api.core.ProviderAPI; import com.tencent.polaris.api.exception.PolarisException; +import com.tencent.polaris.assembly.api.AssemblyAPI; +import com.tencent.polaris.assembly.factory.AssemblyAPIFactory; import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.factory.api.DiscoveryAPIFactory; import com.tencent.polaris.factory.api.RouterAPIFactory; @@ -73,6 +75,11 @@ public class PolarisContextAutoConfiguration { return RouterAPIFactory.createRouterAPIByContext(polarisContext); } + @Bean + public AssemblyAPI assemblyAPI(SDKContext polarisContext) throws PolarisException { + return AssemblyAPIFactory.createAssemblyAPIByContext(polarisContext); + } + @Bean @ConditionalOnMissingBean public ModifyAddress polarisConfigModifier(PolarisContextProperties properties) { diff --git a/spring-cloud-tencent-polaris-loadbalancer/pom.xml b/spring-cloud-tencent-polaris-loadbalancer/pom.xml index a66c3ec9..0c884bc7 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/pom.xml +++ b/spring-cloud-tencent-polaris-loadbalancer/pom.xml @@ -17,7 +17,7 @@ com.tencent.cloud - spring-cloud-tencent-polaris-context + spring-cloud-tencent-rpc-enhancement diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerRingHashKeyProvider.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerRingHashKeyProvider.java index 8a94f799..e07d57dc 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerRingHashKeyProvider.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisLoadBalancerRingHashKeyProvider.java @@ -36,7 +36,7 @@ public final class PolarisLoadBalancerRingHashKeyProvider { } static String getHashKey() { - return MetadataContextHolder.get().getLoadbalancerMetadata().get(LOAD_BALANCER_HASH_KEY); + return (String) MetadataContextHolder.get().getLoadbalancerMetadata().get(LOAD_BALANCER_HASH_KEY); } } diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfiguration.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfiguration.java index bed78f17..571afe5a 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfiguration.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisLoadBalancerAutoConfiguration.java @@ -17,15 +17,24 @@ package com.tencent.cloud.polaris.loadbalancer.config; +import java.util.ArrayList; +import java.util.List; + import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; +import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedRestTemplateInterceptor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor; +import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer; import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonClients; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestInterceptor; /** * Auto-configuration Ribbon for Polaris. @@ -44,4 +53,24 @@ public class PolarisLoadBalancerAutoConfiguration { public PolarisLoadBalancerProperties polarisLoadBalancerProperties() { return new PolarisLoadBalancerProperties(); } + + @Bean + @ConditionalOnMissingBean + public RestTemplateCustomizer restTemplateCustomizer(@Autowired(required = false) LoadBalancerInterceptor loadBalancerInterceptor) { + return restTemplate -> { + List list = new ArrayList<>(restTemplate.getInterceptors()); + // LoadBalancerInterceptor must invoke before EnhancedRestTemplateInterceptor + if (loadBalancerInterceptor != null) { + int addIndex = list.size(); + for (int i = 0; i < list.size(); i++) { + if (list.get(i) instanceof EnhancedRestTemplateInterceptor) { + addIndex = i; + } + } + list.add(addIndex, loadBalancerInterceptor); + } + restTemplate.setInterceptors(list); + }; + } + } 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 58229280..d7651592 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 @@ -24,20 +24,22 @@ import com.netflix.zuul.ZuulFilter; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignBeanPostProcessor; +import com.tencent.cloud.rpc.enhancement.filter.EnhancedReactiveFilter; +import com.tencent.cloud.rpc.enhancement.filter.EnhancedServletFilter; 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.EnhancedRestTemplateInterceptor; -import com.tencent.cloud.rpc.enhancement.resttemplate.RibbonLoadBalancerClientAspect; +import com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer; import com.tencent.cloud.rpc.enhancement.scg.EnhancedGatewayGlobalFilter; -import com.tencent.cloud.rpc.enhancement.webclient.EnhancedWebClientReporter; +import com.tencent.cloud.rpc.enhancement.webclient.EnhancedWebClientExchangeFilterFunction; import com.tencent.cloud.rpc.enhancement.webclient.PolarisLoadBalancerClientRequestTransformer; +import com.tencent.cloud.rpc.enhancement.webclient.RibbonLoadBalancerClientAspect; import com.tencent.cloud.rpc.enhancement.zuul.EnhancedErrorZuulFilter; import com.tencent.cloud.rpc.enhancement.zuul.EnhancedPostZuulFilter; -import com.tencent.cloud.rpc.enhancement.zuul.EnhancedPreZuulFilter; +import com.tencent.cloud.rpc.enhancement.zuul.EnhancedRouteZuulFilter; import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.client.api.SDKContext; @@ -49,16 +51,26 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Role; +import org.springframework.core.annotation.Order; import org.springframework.core.env.Environment; import org.springframework.web.client.RestTemplate; import org.springframework.web.reactive.function.client.WebClient; +import static javax.servlet.DispatcherType.ASYNC; +import static javax.servlet.DispatcherType.ERROR; +import static javax.servlet.DispatcherType.FORWARD; +import static javax.servlet.DispatcherType.INCLUDE; +import static javax.servlet.DispatcherType.REQUEST; + /** * Auto Configuration for Polaris {@link feign.Feign} OR {@link RestTemplate} which can automatically bring in the call * results for reporting. @@ -73,23 +85,55 @@ import org.springframework.web.reactive.function.client.WebClient; public class RpcEnhancementAutoConfiguration { @Bean + @Lazy public EnhancedPluginRunner enhancedFeignPluginRunner( - @Autowired(required = false) List enhancedPlugins) { - return new DefaultEnhancedPluginRunner(enhancedPlugins); + @Autowired(required = false) List enhancedPlugins, + @Autowired(required = false) Registration registration, + SDKContext sdkContext) { + return new DefaultEnhancedPluginRunner(enhancedPlugins, registration, sdkContext); } @Bean public SuccessPolarisReporter successPolarisReporter(RpcEnhancementReporterProperties properties, - SDKContext context, ConsumerAPI consumerAPI) { - return new SuccessPolarisReporter(properties, context, consumerAPI); + return new SuccessPolarisReporter(properties, consumerAPI); } @Bean public ExceptionPolarisReporter exceptionPolarisReporter(RpcEnhancementReporterProperties properties, - SDKContext context, ConsumerAPI consumerAPI) { - return new ExceptionPolarisReporter(properties, context, consumerAPI); + return new ExceptionPolarisReporter(properties, consumerAPI); + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) + protected static class RpcEnhancementServletFilterConfig { + + @Bean + public FilterRegistrationBean enhancedServletFilterRegistrationBean( + EnhancedServletFilter enhancedServletFilter) { + FilterRegistrationBean filterRegistrationBean = + new FilterRegistrationBean<>(enhancedServletFilter); + filterRegistrationBean.setDispatcherTypes(ASYNC, ERROR, FORWARD, INCLUDE, REQUEST); + filterRegistrationBean.setOrder(enhancedServletFilter.getClass().getAnnotation(Order.class).value()); + return filterRegistrationBean; + } + + @Bean + public EnhancedServletFilter enhancedServletFilter(@Lazy EnhancedPluginRunner pluginRunner) { + return new EnhancedServletFilter(pluginRunner); + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) + protected static class RpcEnhancementReactiveFilterConfig { + + @Bean + public EnhancedReactiveFilter enhancedReactiveFilter(@Lazy EnhancedPluginRunner pluginRunner) { + return new EnhancedReactiveFilter(pluginRunner); + } } /** @@ -141,16 +185,9 @@ public class RpcEnhancementAutoConfiguration { @Bean @ConditionalOnMissingBean - @ConditionalOnClass(name = {"org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient"}) - public BlockingLoadBalancerClientAspect blockingLoadBalancerClientAspect() { - return new BlockingLoadBalancerClientAspect(); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnClass(name = {"org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient"}) - public RibbonLoadBalancerClientAspect ribbonLoadBalancerClientAspect() { - return new RibbonLoadBalancerClientAspect(); + @ConditionalOnClass(name = {"org.springframework.cloud.client.loadbalancer.LoadBalancerRequestTransformer"}) + public PolarisLoadBalancerRequestTransformer polarisLoadBalancerRequestTransformer() { + return new PolarisLoadBalancerRequestTransformer(); } } @@ -166,12 +203,12 @@ public class RpcEnhancementAutoConfiguration { private List webClientBuilder = Collections.emptyList(); @Bean - public EnhancedWebClientReporter exchangeFilterFunction(@Lazy EnhancedPluginRunner pluginRunner) { - return new EnhancedWebClientReporter(pluginRunner); + public EnhancedWebClientExchangeFilterFunction exchangeFilterFunction(@Lazy EnhancedPluginRunner pluginRunner) { + return new EnhancedWebClientExchangeFilterFunction(pluginRunner); } @Bean - public SmartInitializingSingleton addEnhancedWebClientReporterForWebClient(EnhancedWebClientReporter reporter) { + public SmartInitializingSingleton addEnhancedWebClientReporterForWebClient(EnhancedWebClientExchangeFilterFunction reporter) { return () -> webClientBuilder.forEach(webClient -> { webClient.filter(reporter); }); @@ -184,6 +221,12 @@ public class RpcEnhancementAutoConfiguration { return new PolarisLoadBalancerClientRequestTransformer(); } + @Bean + @ConditionalOnMissingBean + @ConditionalOnClass(name = {"org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient"}) + public RibbonLoadBalancerClientAspect ribbonLoadBalancerClientAspect() { + return new RibbonLoadBalancerClientAspect(); + } } /** @@ -211,8 +254,8 @@ public class RpcEnhancementAutoConfiguration { @ConditionalOnClass(name = "com.netflix.zuul.http.ZuulServlet") protected static class PolarisCircuitBreakerZuulFilterConfig { @Bean - public EnhancedPreZuulFilter enhancedZuulPreFilter(@Lazy EnhancedPluginRunner pluginRunner, Environment environment) { - return new EnhancedPreZuulFilter(pluginRunner, environment); + public EnhancedRouteZuulFilter enhancedZuulRouteFilter(@Lazy EnhancedPluginRunner pluginRunner, Environment environment) { + return new EnhancedRouteZuulFilter(pluginRunner, environment); } @Bean 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 003dc5f6..37ae78e5 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 @@ -23,6 +23,7 @@ import java.util.ArrayList; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +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 feign.Client; @@ -34,10 +35,6 @@ 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; /** @@ -66,13 +63,19 @@ public class EnhancedFeignClient implements Client { EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder() .httpHeaders(requestHeaders) - .httpMethod(HttpMethod.resolve(request.httpMethod().name())) + .httpMethod(HttpMethod.valueOf(request.httpMethod().name())) .url(url) .build(); enhancedPluginContext.setRequest(enhancedRequestContext); + enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance()); + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(request.requestTemplate().feignTarget() + .name(), url.getHost(), url.getPort(), url.getScheme().equals("https")); + enhancedPluginContext.setTargetServiceInstance(serviceInstance); + // Run pre enhanced plugins. - pluginRunner.run(PRE, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.PRE, enhancedPluginContext); + long startMillis = System.currentTimeMillis(); try { Response response = delegate.execute(request, options); @@ -87,24 +90,20 @@ public class EnhancedFeignClient implements Client { .build(); enhancedPluginContext.setResponse(enhancedResponseContext); - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(request.requestTemplate().feignTarget() - .name(), url.getHost(), url.getPort(), url.getScheme().equals("https")); - enhancedPluginContext.setServiceInstance(serviceInstance); - // Run post enhanced plugins. - pluginRunner.run(POST, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); return response; } catch (IOException origin) { enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); enhancedPluginContext.setThrowable(origin); // Run exception enhanced feign plugins. - pluginRunner.run(EXCEPTION, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.EXCEPTION, enhancedPluginContext); throw origin; } finally { // Run finally enhanced plugins. - pluginRunner.run(FINALLY, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.FINALLY, enhancedPluginContext); } } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/filter/EnhancedReactiveFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/filter/EnhancedReactiveFilter.java new file mode 100644 index 00000000..4fa6899c --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/filter/EnhancedReactiveFilter.java @@ -0,0 +1,93 @@ +/* + * 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.filter; + +import com.tencent.cloud.common.constant.MetadataConstant; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +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 reactor.core.publisher.Mono; + +import org.springframework.core.Ordered; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; + +/** + * EnhancedReactiveFilter. + * + * @author sean yu + */ +public class EnhancedReactiveFilter implements WebFilter, Ordered { + + private final EnhancedPluginRunner pluginRunner; + + public EnhancedReactiveFilter(EnhancedPluginRunner pluginRunner) { + this.pluginRunner = pluginRunner; + } + + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain 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); + + enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance()); + + // Run pre enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.PRE, enhancedPluginContext); + + long startMillis = System.currentTimeMillis(); + return chain.filter(exchange) + .doOnSuccess(v -> { + enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); + + EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder() + .httpStatus(exchange.getResponse().getRawStatusCode()) + .httpHeaders(exchange.getResponse().getHeaders()) + .build(); + enhancedPluginContext.setResponse(enhancedResponseContext); + + // Run post enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.POST, enhancedPluginContext); + }) + .doOnError(e -> { + enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); + enhancedPluginContext.setThrowable(e); + // Run exception enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.EXCEPTION, enhancedPluginContext); + }) + .doFinally(v -> { + // Run finally enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.FINALLY, enhancedPluginContext); + }); + } + + @Override + public int getOrder() { + return MetadataConstant.OrderConstant.WEB_FILTER_ORDER + 1; + } + +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/filter/EnhancedServletFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/filter/EnhancedServletFilter.java new file mode 100644 index 00000000..9d404281 --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/filter/EnhancedServletFilter.java @@ -0,0 +1,116 @@ +/* + * 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.filter; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.tencent.cloud.common.constant.MetadataConstant; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +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 org.springframework.core.annotation.Order; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.web.filter.OncePerRequestFilter; + +/** + * EnhancedServletFilter. + * + * @author sean yu + */ +@Order(MetadataConstant.OrderConstant.WEB_FILTER_ORDER + 1) +public class EnhancedServletFilter extends OncePerRequestFilter { + + private final EnhancedPluginRunner pluginRunner; + + public EnhancedServletFilter(EnhancedPluginRunner pluginRunner) { + this.pluginRunner = pluginRunner; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext(); + + HttpHeaders requestHeaders = new HttpHeaders(); + Enumeration requestHeaderNames = request.getHeaderNames(); + if (requestHeaderNames != null) { + while (requestHeaderNames.hasMoreElements()) { + String requestHeaderName = requestHeaderNames.nextElement(); + requestHeaders.addAll(requestHeaderName, Collections.list(request.getHeaders(requestHeaderName))); + } + } + EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder() + .httpHeaders(requestHeaders) + .httpMethod(HttpMethod.valueOf(request.getMethod())) + .url(URI.create(request.getRequestURL().toString())) + .build(); + enhancedPluginContext.setRequest(enhancedRequestContext); + + enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance()); + + // Run pre enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.PRE, enhancedPluginContext); + + long startMillis = System.currentTimeMillis(); + try { + filterChain.doFilter(request, response); + enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); + + HttpHeaders responseHeaders = new HttpHeaders(); + Collection responseHeaderNames = response.getHeaderNames(); + if (responseHeaderNames != null) { + for (String responseHeaderName : responseHeaderNames) { + responseHeaders.addAll(responseHeaderName, new ArrayList<>(response.getHeaders(responseHeaderName))); + } + } + EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder() + .httpStatus(response.getStatus()) + .httpHeaders(responseHeaders) + .build(); + enhancedPluginContext.setResponse(enhancedResponseContext); + + // Run post enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.POST, enhancedPluginContext); + } + catch (ServletException | IOException e) { + enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); + enhancedPluginContext.setThrowable(e); + // Run exception enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.EXCEPTION, enhancedPluginContext); + throw e; + } + finally { + // Run finally enhanced plugins. + pluginRunner.run(EnhancedPluginType.Server.FINALLY, enhancedPluginContext); + } + } + +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java index ca34b2af..fe88923f 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/DefaultEnhancedPluginRunner.java @@ -23,7 +23,12 @@ import java.util.List; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.polaris.client.api.SDKContext; +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.util.CollectionUtils; /** @@ -33,13 +38,28 @@ import org.springframework.util.CollectionUtils; */ public class DefaultEnhancedPluginRunner implements EnhancedPluginRunner { - private final Multimap pluginMap = ArrayListMultimap.create(); + private final Multimap pluginMap = ArrayListMultimap.create(); - public DefaultEnhancedPluginRunner(List enhancedPlugins) { + private final ServiceInstance localServiceInstance; + + public DefaultEnhancedPluginRunner( + List enhancedPlugins, + Registration registration, + SDKContext sdkContext + ) { if (!CollectionUtils.isEmpty(enhancedPlugins)) { enhancedPlugins.stream() .sorted(Comparator.comparing(EnhancedPlugin::getOrder)) - .forEach(plugin -> pluginMap.put(plugin.getType().name(), plugin)); + .forEach(plugin -> pluginMap.put(plugin.getType(), plugin)); + } + if (registration != null) { + localServiceInstance = registration; + } + else { + DefaultServiceInstance defaultServiceInstance = new DefaultServiceInstance(); + defaultServiceInstance.setServiceId(MetadataContext.LOCAL_SERVICE); + defaultServiceInstance.setHost(sdkContext.getConfig().getGlobal().getAPI().getBindIP()); + localServiceInstance = defaultServiceInstance; } } @@ -51,7 +71,7 @@ public class DefaultEnhancedPluginRunner implements EnhancedPluginRunner { */ @Override public void run(EnhancedPluginType pluginType, EnhancedPluginContext context) { - for (EnhancedPlugin plugin : pluginMap.get(pluginType.name())) { + for (EnhancedPlugin plugin : pluginMap.get(pluginType)) { try { plugin.run(context); } @@ -60,4 +80,10 @@ public class DefaultEnhancedPluginRunner implements EnhancedPluginRunner { } } } + + @Override + public ServiceInstance getLocalServiceInstance() { + return this.localServiceInstance; + } + } 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 index fa4e891d..4676c51a 100644 --- 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 @@ -35,7 +35,12 @@ public class EnhancedPluginContext { private long delay; - private ServiceInstance serviceInstance; + private ServiceInstance localServiceInstance; + + /** + * targetServiceInstance only exist in a client runner type. + */ + private ServiceInstance targetServiceInstance; public EnhancedRequestContext getRequest() { return request; @@ -69,12 +74,20 @@ public class EnhancedPluginContext { this.delay = delay; } - public ServiceInstance getServiceInstance() { - return serviceInstance; + public ServiceInstance getLocalServiceInstance() { + return localServiceInstance; + } + + public void setLocalServiceInstance(ServiceInstance localServiceInstance) { + this.localServiceInstance = localServiceInstance; } - public void setServiceInstance(ServiceInstance serviceInstance) { - this.serviceInstance = serviceInstance; + public ServiceInstance getTargetServiceInstance() { + return targetServiceInstance; + } + + public void setTargetServiceInstance(ServiceInstance targetServiceInstance) { + this.targetServiceInstance = targetServiceInstance; } @Override @@ -84,7 +97,9 @@ public class EnhancedPluginContext { ", response=" + response + ", throwable=" + throwable + ", delay=" + delay + - ", serviceInstance=" + serviceInstance + + ", localServiceInstance=" + localServiceInstance + + ", targetServiceInstance=" + targetServiceInstance + '}'; } + } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java index e15af39e..5ff7d1bf 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginRunner.java @@ -18,6 +18,8 @@ package com.tencent.cloud.rpc.enhancement.plugin; +import org.springframework.cloud.client.ServiceInstance; + /** * Plugin runner. * @@ -32,4 +34,7 @@ public interface EnhancedPluginRunner { * @param context context in enhanced feign client. */ void run(EnhancedPluginType pluginType, EnhancedPluginContext context); + + ServiceInstance getLocalServiceInstance(); + } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java index 64dc2ecb..996af00b 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginType.java @@ -22,25 +22,52 @@ package com.tencent.cloud.rpc.enhancement.plugin; * * @author Haotian Zhang */ -public enum EnhancedPluginType { - - /** - * Pre feign plugin. - */ - PRE, - - /** - * Post feign plugin. - */ - POST, - - /** - * Exception feign plugin. - */ - EXCEPTION, - - /** - * Finally feign plugin. - */ - FINALLY +public interface EnhancedPluginType { + + enum Client implements EnhancedPluginType { + /** + * Pre Client plugin. + */ + PRE, + + /** + * Post Client plugin. + */ + POST, + + /** + * Exception Client plugin. + */ + EXCEPTION, + + /** + * Finally Client plugin. + */ + FINALLY + + } + + enum Server implements EnhancedPluginType { + /** + * Pre Server plugin. + */ + PRE, + + /** + * Post Server plugin. + */ + POST, + + /** + * Exception Server plugin. + */ + EXCEPTION, + + /** + * Finally Server plugin. + */ + FINALLY + + } + } 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/plugin/PolarisEnhancedPluginUtils.java similarity index 73% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapter.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PolarisEnhancedPluginUtils.java index d177aad8..e1556c82 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/plugin/PolarisEnhancedPluginUtils.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.rpc.enhancement; +package com.tencent.cloud.rpc.enhancement.plugin; import java.io.UnsupportedEncodingException; import java.net.SocketTimeoutException; @@ -24,12 +24,18 @@ import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.constant.RouterConstant; import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.common.util.RequestLabelUtils; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat; @@ -39,11 +45,11 @@ import com.tencent.polaris.api.pojo.RetStatus; import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.api.rpc.ServiceCallResult; import com.tencent.polaris.api.utils.CollectionUtils; -import com.tencent.polaris.client.api.SDKContext; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.lang.Nullable; @@ -63,30 +69,21 @@ import static org.springframework.http.HttpStatus.SERVICE_UNAVAILABLE; import static org.springframework.http.HttpStatus.VARIANT_ALSO_NEGOTIATES; /** - * Abstract Polaris Reporter Adapter . + * Abstract Polaris Plugin Adapter . * * @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, - INSUFFICIENT_STORAGE, LOOP_DETECTED, BANDWIDTH_LIMIT_EXCEEDED, NOT_EXTENDED, NETWORK_AUTHENTICATION_REQUIRED); +public final class PolarisEnhancedPluginUtils { - protected final RpcEnhancementReporterProperties reportProperties; + private PolarisEnhancedPluginUtils() { - protected final SDKContext context; - - /** - * Constructor With {@link RpcEnhancementReporterProperties} . - * - * @param reportProperties instance of {@link RpcEnhancementReporterProperties}. - */ - protected AbstractPolarisReporterAdapter(RpcEnhancementReporterProperties reportProperties, SDKContext context) { - this.reportProperties = reportProperties; - this.context = context; } + private static final Logger LOG = LoggerFactory.getLogger(PolarisEnhancedPluginUtils.class); + private static final List HTTP_STATUSES = toList(NOT_IMPLEMENTED, BAD_GATEWAY, + SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT, HTTP_VERSION_NOT_SUPPORTED, VARIANT_ALSO_NEGOTIATES, + INSUFFICIENT_STORAGE, LOOP_DETECTED, BANDWIDTH_LIMIT_EXCEEDED, NOT_EXTENDED, NETWORK_AUTHENTICATION_REQUIRED); + /** * createServiceCallResult. * @param calleeServiceName will pick up url host when null @@ -100,7 +97,7 @@ public abstract class AbstractPolarisReporterAdapter { * @param exception exception * @return ServiceCallResult */ - public ServiceCallResult createServiceCallResult( + public static ServiceCallResult createServiceCallResult(String callerHost, @Nullable String calleeServiceName, @Nullable String calleeHost, @Nullable Integer calleePort, URI uri, HttpHeaders requestHeaders, @Nullable HttpHeaders responseHeaders, @Nullable Integer statusCode, long delay, @Nullable Throwable exception) { @@ -112,11 +109,11 @@ public abstract class AbstractPolarisReporterAdapter { resultRequest.setRetCode(statusCode == null ? -1 : statusCode); resultRequest.setDelay(delay); resultRequest.setCallerService(new ServiceKey(MetadataContext.LOCAL_NAMESPACE, MetadataContext.LOCAL_SERVICE)); - resultRequest.setCallerIp(this.context.getConfig().getGlobal().getAPI().getBindIP()); + resultRequest.setCallerIp(callerHost); resultRequest.setHost(StringUtils.isBlank(calleeHost) ? uri.getHost() : calleeHost); resultRequest.setPort(calleePort == null ? getPort(uri) : calleePort); resultRequest.setLabels(getLabels(requestHeaders)); - resultRequest.setRetStatus(getRetStatusFromRequest(responseHeaders, getDefaultRetStatus(statusCode, exception))); + resultRequest.setRetStatus(getRetStatusFromRequest(responseHeaders, statusCode, exception)); resultRequest.setRuleName(getActiveRuleNameFromRequest(responseHeaders)); return resultRequest; } @@ -132,7 +129,7 @@ public abstract class AbstractPolarisReporterAdapter { * @param exception exception * @return ResourceStat */ - public ResourceStat createInstanceResourceStat( + public static ResourceStat createInstanceResourceStat( @Nullable String calleeServiceName, @Nullable String calleeHost, @Nullable Integer calleePort, URI uri, @Nullable Integer statusCode, long delay, @Nullable Throwable exception) { ServiceKey calleeServiceKey = new ServiceKey(MetadataContext.LOCAL_NAMESPACE, StringUtils.isBlank(calleeServiceName) ? uri.getHost() : calleeServiceName); @@ -165,42 +162,40 @@ public abstract class AbstractPolarisReporterAdapter { * @param httpStatus request http status code * @return true , otherwise return false . */ - protected boolean apply(@Nullable HttpStatus httpStatus) { + static boolean apply(@Nullable HttpStatus httpStatus) { if (Objects.isNull(httpStatus)) { return false; } - else { - // statuses > series - List status = reportProperties.getStatuses(); - - if (status.isEmpty()) { - List series = reportProperties.getSeries(); - // Check INTERNAL_SERVER_ERROR (500) status. - if (reportProperties.isIgnoreInternalServerError() && Objects.equals(httpStatus, INTERNAL_SERVER_ERROR)) { - return false; - } - if (series.isEmpty()) { - return HTTP_STATUSES.contains(httpStatus); - } - else { - try { - return series.contains(HttpStatus.Series.valueOf(httpStatus)); - } - catch (Exception e) { - LOG.warn("Decode http status failed.", e); - } - } + RpcEnhancementReporterProperties reportProperties; + try { + reportProperties = ApplicationContextAwareUtils.getApplicationContext().getBean(RpcEnhancementReporterProperties.class); + } + catch (BeansException e) { + LOG.error("get RpcEnhancementReporterProperties bean err", e); + reportProperties = new RpcEnhancementReporterProperties(); + } + // statuses > series + List status = reportProperties.getStatuses(); + if (status.isEmpty()) { + List series = reportProperties.getSeries(); + // Check INTERNAL_SERVER_ERROR (500) status. + if (reportProperties.isIgnoreInternalServerError() && Objects.equals(httpStatus, INTERNAL_SERVER_ERROR)) { + return false; } - else { - // Use the user-specified fuse status code. - return status.contains(httpStatus); + if (series.isEmpty()) { + return HTTP_STATUSES.contains(httpStatus); } + return series.contains(httpStatus.series()); } - // DEFAULT RETURN FALSE. - return false; + // Use the user-specified fuse status code. + return status.contains(httpStatus); + } + + public static RetStatus getRetStatusFromRequest(HttpHeaders headers, Integer statusCode, Throwable exception) { + return getRetStatusFromRequest(headers, getDefaultRetStatus(statusCode, exception)); } - protected RetStatus getRetStatusFromRequest(HttpHeaders headers, RetStatus defaultVal) { + static RetStatus getRetStatusFromRequest(HttpHeaders headers, RetStatus defaultVal) { if (headers != null && headers.containsKey(HeaderConstant.INTERNAL_CALLEE_RET_STATUS)) { List values = headers.get(HeaderConstant.INTERNAL_CALLEE_RET_STATUS); if (CollectionUtils.isNotEmpty(values)) { @@ -216,7 +211,7 @@ public abstract class AbstractPolarisReporterAdapter { return defaultVal; } - protected String getActiveRuleNameFromRequest(HttpHeaders headers) { + static String getActiveRuleNameFromRequest(HttpHeaders headers) { if (headers != null && headers.containsKey(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME)) { Collection values = headers.get(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME); if (CollectionUtils.isNotEmpty(values)) { @@ -226,7 +221,7 @@ public abstract class AbstractPolarisReporterAdapter { return ""; } - private RetStatus getDefaultRetStatus(Integer statusCode, Throwable exception) { + private static RetStatus getDefaultRetStatus(Integer statusCode, Throwable exception) { RetStatus retStatus = RetStatus.RetSuccess; if (exception != null) { retStatus = RetStatus.RetFail; @@ -240,12 +235,12 @@ public abstract class AbstractPolarisReporterAdapter { return retStatus; } - private int getPort(URI uri) { + private static int getPort(URI uri) { // -1 means access directly by url, and use http default port number 80 return uri.getPort() == -1 ? 80 : uri.getPort(); } - private String getLabels(HttpHeaders headers) { + private static String getLabels(HttpHeaders headers) { if (headers != null) { Collection labels = headers.get(RouterConstant.ROUTER_LABEL_HEADER); if (CollectionUtils.isNotEmpty(labels) && labels.iterator().hasNext()) { @@ -262,5 +257,27 @@ public abstract class AbstractPolarisReporterAdapter { return null; } + public static Map getLabelMap(HttpHeaders headers) { + 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); + } + try { + return new ObjectMapper().readValue(label, new TypeReference>() { }); + } + catch (JsonProcessingException e) { + LOG.error("parse label map exception", e); + } + } + } + return null; + } + } 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 index 9fb1cdd4..471c9a17 100644 --- 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 @@ -20,15 +20,14 @@ 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.PolarisEnhancedPluginUtils; 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; @@ -42,16 +41,17 @@ import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.Clien * * @author Haotian Zhang */ -public class ExceptionPolarisReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { +public class ExceptionPolarisReporter implements EnhancedPlugin { private static final Logger LOG = LoggerFactory.getLogger(ExceptionPolarisReporter.class); private final ConsumerAPI consumerAPI; - public ExceptionPolarisReporter(RpcEnhancementReporterProperties reporterProperties, - SDKContext context, + private final RpcEnhancementReporterProperties reportProperties; + + public ExceptionPolarisReporter(RpcEnhancementReporterProperties reportProperties, ConsumerAPI consumerAPI) { - super(reporterProperties, context); + this.reportProperties = reportProperties; this.consumerAPI = consumerAPI; } @@ -62,23 +62,24 @@ public class ExceptionPolarisReporter extends AbstractPolarisReporterAdapter imp @Override public EnhancedPluginType getType() { - return EnhancedPluginType.EXCEPTION; + return EnhancedPluginType.Client.EXCEPTION; } @Override public void run(EnhancedPluginContext context) { - if (!super.reportProperties.isEnabled()) { + if (!this.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(), + ServiceInstance callerServiceInstance = Optional.ofNullable(context.getLocalServiceInstance()).orElse(new DefaultServiceInstance()); + ServiceInstance calleeServiceInstance = Optional.ofNullable(context.getTargetServiceInstance()).orElse(new DefaultServiceInstance()); + + ServiceCallResult resultRequest = PolarisEnhancedPluginUtils.createServiceCallResult( + callerServiceInstance.getHost(), + calleeServiceInstance.getServiceId(), + calleeServiceInstance.getHost(), + calleeServiceInstance.getPort(), request.getUrl(), request.getHttpHeaders(), null, @@ -88,8 +89,7 @@ public class ExceptionPolarisReporter extends AbstractPolarisReporterAdapter imp ); LOG.debug("Will report ServiceCallResult of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", - resultRequest.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl() - .getPath(), context.getThrowable().getMessage(), context.getDelay()); + resultRequest.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), context.getThrowable().getMessage(), context.getDelay()); consumerAPI.updateServiceCallResult(resultRequest); 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 index 6fddf0f8..d4c7d6a1 100644 --- 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 @@ -19,16 +19,15 @@ 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.cloud.rpc.enhancement.plugin.PolarisEnhancedPluginUtils; 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; @@ -42,16 +41,17 @@ import static com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant.Clien * * @author Haotian Zhang */ -public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter implements EnhancedPlugin { +public class SuccessPolarisReporter implements EnhancedPlugin { private static final Logger LOG = LoggerFactory.getLogger(SuccessPolarisReporter.class); private final ConsumerAPI consumerAPI; - public SuccessPolarisReporter(RpcEnhancementReporterProperties properties, - SDKContext context, + private final RpcEnhancementReporterProperties reportProperties; + + public SuccessPolarisReporter(RpcEnhancementReporterProperties reportProperties, ConsumerAPI consumerAPI) { - super(properties, context); + this.reportProperties = reportProperties; this.consumerAPI = consumerAPI; } @@ -62,24 +62,25 @@ public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter imple @Override public EnhancedPluginType getType() { - return EnhancedPluginType.POST; + return EnhancedPluginType.Client.POST; } @Override public void run(EnhancedPluginContext context) { - if (!super.reportProperties.isEnabled()) { + if (!this.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(), + ServiceInstance callerServiceInstance = Optional.ofNullable(context.getLocalServiceInstance()).orElse(new DefaultServiceInstance()); + ServiceInstance calleeServiceInstance = Optional.ofNullable(context.getTargetServiceInstance()).orElse(new DefaultServiceInstance()); + + ServiceCallResult resultRequest = PolarisEnhancedPluginUtils.createServiceCallResult( + callerServiceInstance.getHost(), + calleeServiceInstance.getServiceId(), + calleeServiceInstance.getHost(), + calleeServiceInstance.getPort(), request.getUrl(), request.getHttpHeaders(), response.getHttpHeaders(), @@ -89,8 +90,7 @@ public class SuccessPolarisReporter extends AbstractPolarisReporterAdapter imple ); LOG.debug("Will report ServiceCallResult of {}. Request=[{} {}]. Response=[{}]. Delay=[{}]ms.", - resultRequest.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl() - .getPath(), response.getHttpStatus(), context.getDelay()); + resultRequest.getRetStatus().name(), request.getHttpMethod().name(), request.getUrl().getPath(), response.getHttpStatus(), context.getDelay()); consumerAPI.updateServiceCallResult(resultRequest); diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspect.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspect.java deleted file mode 100644 index 418ce484..00000000 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspect.java +++ /dev/null @@ -1,43 +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 org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; - -/** - * Intercept for BlockingLoadBalancerClient, put host and port to thread local. - * - * @author lepdou 2022-09-05 - */ -@Aspect -public class BlockingLoadBalancerClientAspect { - - @Pointcut("execution(public * org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient.reconstructURI(..)) ") - public void pointcut() { - - } - - @Around("pointcut()") - public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable { - LoadBalancerClientAspectUtils.extractLoadBalancerResult(joinPoint); - return joinPoint.proceed(); - } -} diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptor.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptor.java index e67e241f..2a4e0f6f 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptor.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptor.java @@ -18,25 +18,21 @@ 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.EnhancedPluginType; 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.cloud.client.ServiceInstance; 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; +import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE; /** * EnhancedRestTemplateInterceptor. @@ -63,8 +59,13 @@ public class EnhancedRestTemplateInterceptor implements ClientHttpRequestInterce .build(); enhancedPluginContext.setRequest(enhancedRequestContext); + enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance()); + enhancedPluginContext.setTargetServiceInstance( + (ServiceInstance) MetadataContextHolder.get().getLoadbalancerMetadata().get(LOAD_BALANCER_SERVICE_INSTANCE)); + // Run pre enhanced plugins. - pluginRunner.run(PRE, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.PRE, enhancedPluginContext); + long startMillis = System.currentTimeMillis(); try { ClientHttpResponse response = execution.execute(request, body); @@ -76,29 +77,20 @@ public class EnhancedRestTemplateInterceptor implements ClientHttpRequestInterce .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); + pluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); return response; } catch (IOException e) { enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis); enhancedPluginContext.setThrowable(e); // Run exception enhanced plugins. - pluginRunner.run(EXCEPTION, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.EXCEPTION, enhancedPluginContext); throw e; } finally { // Run finally enhanced plugins. - pluginRunner.run(FINALLY, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.FINALLY, enhancedPluginContext); } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisLoadBalancerRequestTransformer.java similarity index 55% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisLoadBalancerRequestTransformer.java index 04ffac0c..961633cf 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/LoadBalancerClientAspectUtils.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisLoadBalancerRequestTransformer.java @@ -17,28 +17,36 @@ package com.tencent.cloud.rpc.enhancement.resttemplate; -import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.metadata.MetadataContextHolder; -import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; +import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestTransformer; +import org.springframework.http.HttpRequest; /** - * Extract load balancer result from {@link LoadBalancerClient} and put to MetadataContext. - * @author lepdou 2022-09-06 + * PolarisLoadBalancerRequestTransformer. + * + * @author sean yu */ -public final class LoadBalancerClientAspectUtils { +public class PolarisLoadBalancerRequestTransformer implements LoadBalancerRequestTransformer { - private LoadBalancerClientAspectUtils() { - } + /** + * LOAD_BALANCER_SERVICE_INSTANCE MetadataContext key. + */ + public static final String LOAD_BALANCER_SERVICE_INSTANCE = "LOAD_BALANCER_SERVICE_INSTANCE"; - public static void extractLoadBalancerResult(ProceedingJoinPoint joinPoint) { - Object server = joinPoint.getArgs()[0]; - if (server instanceof ServiceInstance) { - ServiceInstance instance = (ServiceInstance) server; - MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST, instance.getHost()); - MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT, String.valueOf(instance.getPort())); + /** + * Transform Request, add Loadbalancer ServiceInstance to MetadataContext. + * @param request request + * @param instance instance + * @return HttpRequest + */ + @Override + public HttpRequest transformRequest(HttpRequest request, ServiceInstance instance) { + if (instance != null) { + MetadataContextHolder.get().setLoadbalancer(LOAD_BALANCER_SERVICE_INSTANCE, instance); } + return request; } + } 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 index 6f0a0261..a76b5507 100644 --- 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 @@ -21,6 +21,7 @@ import java.net.URI; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +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 reactor.core.publisher.Mono; @@ -33,10 +34,6 @@ import org.springframework.cloud.gateway.route.Route; 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.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR; @@ -64,8 +61,15 @@ public class EnhancedGatewayGlobalFilter implements GlobalFilter, Ordered { .build(); enhancedPluginContext.setRequest(enhancedRequestContext); +// enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance()); +// Response serviceInstanceResponse = exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR); +// if (serviceInstanceResponse != null && serviceInstanceResponse.hasServer()) { +// ServiceInstance instance = serviceInstanceResponse.getServer(); +// enhancedPluginContext.setTargetServiceInstance(instance); +// } + // Run pre enhanced plugins. - pluginRunner.run(PRE, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.PRE, enhancedPluginContext); long startTime = System.currentTimeMillis(); return chain.filter(exchange) @@ -80,7 +84,7 @@ public class EnhancedGatewayGlobalFilter implements GlobalFilter, Ordered { serviceInstance.setHost(uri.getHost()); serviceInstance.setPort(uri.getPort()); } - enhancedPluginContext.setServiceInstance(serviceInstance); + enhancedPluginContext.setTargetServiceInstance(serviceInstance); }) .doOnSuccess(v -> { enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime); @@ -91,18 +95,18 @@ public class EnhancedGatewayGlobalFilter implements GlobalFilter, Ordered { enhancedPluginContext.setResponse(enhancedResponseContext); // Run post enhanced plugins. - pluginRunner.run(POST, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); }) .doOnError(t -> { enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime); enhancedPluginContext.setThrowable(t); // Run exception enhanced plugins. - pluginRunner.run(EXCEPTION, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.EXCEPTION, enhancedPluginContext); }) .doFinally(v -> { // Run finally enhanced plugins. - pluginRunner.run(FINALLY, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.FINALLY, enhancedPluginContext); }); } 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/EnhancedWebClientExchangeFilterFunction.java similarity index 68% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporter.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientExchangeFilterFunction.java index 2b62fc5d..2d5577fc 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/EnhancedWebClientExchangeFilterFunction.java @@ -17,35 +17,31 @@ package com.tencent.cloud.rpc.enhancement.webclient; -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.EnhancedPluginType; 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.DefaultServiceInstance; +import org.springframework.cloud.client.ServiceInstance; 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; +import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE; /** - * EnhancedWebClientReporter. + * EnhancedWebClientExchangeFilterFunction. * * @author sean yu */ -public class EnhancedWebClientReporter implements ExchangeFilterFunction { +public class EnhancedWebClientExchangeFilterFunction implements ExchangeFilterFunction { private final EnhancedPluginRunner pluginRunner; - public EnhancedWebClientReporter(EnhancedPluginRunner pluginRunner) { + public EnhancedWebClientExchangeFilterFunction(EnhancedPluginRunner pluginRunner) { this.pluginRunner = pluginRunner; } @@ -60,38 +56,37 @@ public class EnhancedWebClientReporter implements ExchangeFilterFunction { .build(); enhancedPluginContext.setRequest(enhancedRequestContext); + enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance()); + enhancedPluginContext.setTargetServiceInstance( + (ServiceInstance) MetadataContextHolder.get().getLoadbalancerMetadata().get(LOAD_BALANCER_SERVICE_INSTANCE)); + + // Run post enhanced plugins. + pluginRunner.run(EnhancedPluginType.Client.PRE, enhancedPluginContext); + long startTime = System.currentTimeMillis(); return next.exchange(request) - .doOnSubscribe(subscription -> { - 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); - }) .doOnSuccess(response -> { enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime); EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder() - .httpStatus(response.rawStatusCode()) + .httpStatus(response.statusCode().value()) .httpHeaders(response.headers().asHttpHeaders()) .build(); enhancedPluginContext.setResponse(enhancedResponseContext); // Run post enhanced plugins. - pluginRunner.run(POST, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); }) .doOnError(t -> { enhancedPluginContext.setDelay(System.currentTimeMillis() - startTime); enhancedPluginContext.setThrowable(t); // Run exception enhanced plugins. - pluginRunner.run(EXCEPTION, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.EXCEPTION, enhancedPluginContext); }) .doFinally(v -> { // Run finally enhanced plugins. - pluginRunner.run(FINALLY, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.FINALLY, enhancedPluginContext); }); } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformer.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformer.java index 4e691316..be1807ff 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformer.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformer.java @@ -17,13 +17,14 @@ package com.tencent.cloud.rpc.enhancement.webclient; -import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.metadata.MetadataContextHolder; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerClientRequestTransformer; import org.springframework.web.reactive.function.client.ClientRequest; +import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE; + /** * PolarisLoadBalancerClientRequestTransformer. * @@ -31,10 +32,16 @@ import org.springframework.web.reactive.function.client.ClientRequest; */ public class PolarisLoadBalancerClientRequestTransformer implements LoadBalancerClientRequestTransformer { + /** + * Transform Request, add Loadbalancer ServiceInstance to MetadataContext. + * @param request request + * @param instance instance + * @return HttpRequest + */ @Override public ClientRequest transformRequest(ClientRequest request, ServiceInstance instance) { if (instance != null) { - MetadataContextHolder.get().setLoadbalancer(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID, instance.getServiceId()); + MetadataContextHolder.get().setLoadbalancer(LOAD_BALANCER_SERVICE_INSTANCE, instance); } return request; } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/RibbonLoadBalancerClientAspect.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/RibbonLoadBalancerClientAspect.java similarity index 73% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/RibbonLoadBalancerClientAspect.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/RibbonLoadBalancerClientAspect.java index 59f3ec90..64ff67ba 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/RibbonLoadBalancerClientAspect.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/webclient/RibbonLoadBalancerClientAspect.java @@ -15,13 +15,16 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.rpc.enhancement.resttemplate; +package com.tencent.cloud.rpc.enhancement.webclient; +import com.tencent.cloud.common.metadata.MetadataContextHolder; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; +import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE; + /** * Intercept for RibbonLoadBalancerClient, put host and port to thread local. * @@ -30,14 +33,17 @@ import org.aspectj.lang.annotation.Pointcut; @Aspect public class RibbonLoadBalancerClientAspect { - @Pointcut("execution(public * org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.reconstructURI(..))") + @Pointcut("execution(public * org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.choose(..))") public void pointcut() { } @Around("pointcut()") public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable { - LoadBalancerClientAspectUtils.extractLoadBalancerResult(joinPoint); - return joinPoint.proceed(); + Object result = joinPoint.proceed(); + if (result != null) { + MetadataContextHolder.get().setLoadbalancer(LOAD_BALANCER_SERVICE_INSTANCE, result); + } + return result; } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedErrorZuulFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedErrorZuulFilter.java index 362e9be0..778b8132 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedErrorZuulFilter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedErrorZuulFilter.java @@ -24,22 +24,18 @@ import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import com.tencent.cloud.common.constant.ContextConstant; -import com.tencent.cloud.common.util.ZuulFilterUtils; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponse; import org.springframework.core.env.Environment; import org.springframework.http.HttpHeaders; import org.springframework.util.StringUtils; import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_PRE_ROUTE_TIME; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.EXCEPTION; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ERROR_TYPE; /** @@ -90,13 +86,9 @@ public class EnhancedErrorZuulFilter extends ZuulFilter { enhancedPluginContext = (EnhancedPluginContext) enhancedPluginContextObj; } - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); - Object ribbonResponseObj = context.get("ribbonResponse"); Object startTimeMilliObject = context.get(POLARIS_PRE_ROUTE_TIME); Throwable throwable = context.getThrowable(); - RibbonApacheHttpResponse ribbonResponse; - if (throwable != null && ribbonResponseObj != null && ribbonResponseObj instanceof RibbonApacheHttpResponse - && startTimeMilliObject != null && startTimeMilliObject instanceof Long) { + if (throwable != null && startTimeMilliObject != null && startTimeMilliObject instanceof Long) { HttpHeaders responseHeaders = new HttpHeaders(); Collection names = context.getResponse().getHeaderNames(); for (String name : names) { @@ -110,17 +102,12 @@ public class EnhancedErrorZuulFilter extends ZuulFilter { Long startTimeMilli = (Long) startTimeMilliObject; enhancedPluginContext.setDelay(System.currentTimeMillis() - startTimeMilli); enhancedPluginContext.setThrowable(throwable); - ribbonResponse = (RibbonApacheHttpResponse) ribbonResponseObj; - serviceInstance.setServiceId(ZuulFilterUtils.getServiceId(context)); - serviceInstance.setHost(ribbonResponse.getRequestedURI().getHost()); - serviceInstance.setPort(ribbonResponse.getRequestedURI().getPort()); - enhancedPluginContext.setServiceInstance(serviceInstance); // Run post enhanced plugins. - pluginRunner.run(EXCEPTION, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.EXCEPTION, enhancedPluginContext); // Run finally enhanced plugins. - pluginRunner.run(FINALLY, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.FINALLY, enhancedPluginContext); } return null; } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPostZuulFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPostZuulFilter.java index ff1ba409..9ee46638 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPostZuulFilter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPostZuulFilter.java @@ -24,22 +24,18 @@ import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import com.tencent.cloud.common.constant.ContextConstant; -import com.tencent.cloud.common.util.ZuulFilterUtils; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponse; import org.springframework.core.env.Environment; import org.springframework.http.HttpHeaders; import org.springframework.util.StringUtils; import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_PRE_ROUTE_TIME; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.FINALLY; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.POST; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER; @@ -89,12 +85,8 @@ public class EnhancedPostZuulFilter extends ZuulFilter { enhancedPluginContext = (EnhancedPluginContext) enhancedPluginContextObj; } - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); - Object ribbonResponseObj = context.get("ribbonResponse"); Object startTimeMilliObject = context.get(POLARIS_PRE_ROUTE_TIME); - RibbonApacheHttpResponse ribbonResponse; - if (ribbonResponseObj != null && ribbonResponseObj instanceof RibbonApacheHttpResponse - && startTimeMilliObject != null && startTimeMilliObject instanceof Long) { + if (startTimeMilliObject instanceof Long) { HttpHeaders responseHeaders = new HttpHeaders(); Collection names = context.getResponse().getHeaderNames(); for (String name : names) { @@ -107,17 +99,12 @@ public class EnhancedPostZuulFilter extends ZuulFilter { enhancedPluginContext.setResponse(enhancedResponseContext); Long startTimeMilli = (Long) startTimeMilliObject; enhancedPluginContext.setDelay(System.currentTimeMillis() - startTimeMilli); - ribbonResponse = (RibbonApacheHttpResponse) ribbonResponseObj; - serviceInstance.setServiceId(ZuulFilterUtils.getServiceId(context)); - serviceInstance.setHost(ribbonResponse.getRequestedURI().getHost()); - serviceInstance.setPort(ribbonResponse.getRequestedURI().getPort()); - enhancedPluginContext.setServiceInstance(serviceInstance); // Run post enhanced plugins. - pluginRunner.run(POST, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); // Run finally enhanced plugins. - pluginRunner.run(FINALLY, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.FINALLY, enhancedPluginContext); } return null; } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPreZuulFilter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedRouteZuulFilter.java similarity index 74% rename from spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPreZuulFilter.java rename to spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedRouteZuulFilter.java index 65484c13..e849e4c8 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedPreZuulFilter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/zuul/EnhancedRouteZuulFilter.java @@ -29,46 +29,48 @@ import com.tencent.cloud.common.constant.ContextConstant; import com.tencent.cloud.common.util.ZuulFilterUtils; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponse; import org.springframework.core.env.Environment; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.util.StringUtils; import static com.tencent.cloud.common.constant.ContextConstant.Zuul.POLARIS_PRE_ROUTE_TIME; -import static com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType.PRE; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER; -import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; +import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.RIBBON_ROUTING_FILTER_ORDER; +import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE; /** * Polaris circuit breaker implement in Zuul. * * @author Haotian Zhang */ -public class EnhancedPreZuulFilter extends ZuulFilter { +public class EnhancedRouteZuulFilter extends ZuulFilter { - private static final Logger LOGGER = LoggerFactory.getLogger(EnhancedPreZuulFilter.class); + private static final Logger LOGGER = LoggerFactory.getLogger(EnhancedRouteZuulFilter.class); private final EnhancedPluginRunner pluginRunner; private final Environment environment; - public EnhancedPreZuulFilter(EnhancedPluginRunner pluginRunner, Environment environment) { + public EnhancedRouteZuulFilter(EnhancedPluginRunner pluginRunner, Environment environment) { this.pluginRunner = pluginRunner; this.environment = environment; } @Override public String filterType() { - return PRE_TYPE; + return ROUTE_TYPE; } @Override public int filterOrder() { - return PRE_DECORATION_FILTER_ORDER + 1; + return RIBBON_ROUTING_FILTER_ORDER + 1; } @Override @@ -100,9 +102,21 @@ public class EnhancedPreZuulFilter extends ZuulFilter { .build(); enhancedPluginContext.setRequest(enhancedRequestContext); + enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance()); + + Object ribbonResponseObj = context.get("ribbonResponse"); + RibbonApacheHttpResponse ribbonResponse; + DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); + if (ribbonResponseObj != null && ribbonResponseObj instanceof RibbonApacheHttpResponse) { + ribbonResponse = (RibbonApacheHttpResponse) ribbonResponseObj; + serviceInstance.setServiceId(ZuulFilterUtils.getServiceId(context)); + serviceInstance.setHost(ribbonResponse.getRequestedURI().getHost()); + serviceInstance.setPort(ribbonResponse.getRequestedURI().getPort()); + enhancedPluginContext.setTargetServiceInstance(serviceInstance); + } // Run pre enhanced plugins. - pluginRunner.run(PRE, enhancedPluginContext); + pluginRunner.run(EnhancedPluginType.Client.PRE, enhancedPluginContext); Object startTimeMilliObject = context.get(POLARIS_PRE_ROUTE_TIME); if (startTimeMilliObject == null || !(startTimeMilliObject instanceof Long)) { 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 2ff9ff90..faa02de8 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 @@ -26,6 +26,7 @@ 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 com.tencent.polaris.client.api.SDKContext; import feign.Client; import feign.Request; import feign.RequestTemplate; @@ -34,6 +35,7 @@ import feign.Target; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -55,6 +57,9 @@ import static org.mockito.Mockito.mock; properties = {"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp", "spring.cloud.gateway.enabled=false"}) public class EnhancedFeignClientTest { + @Autowired + private SDKContext sdkContext; + @Test public void testConstructor() { try { @@ -75,7 +80,7 @@ public class EnhancedFeignClientTest { List enhancedPlugins = getMockEnhancedFeignPlugins(); try { - new EnhancedFeignClient(mock(Client.class), new DefaultEnhancedPluginRunner(enhancedPlugins)); + new EnhancedFeignClient(mock(Client.class), new DefaultEnhancedPluginRunner(enhancedPlugins, null, sdkContext)); } catch (Throwable e) { fail("Exception encountered.", e); @@ -104,7 +109,7 @@ public class EnhancedFeignClientTest { RequestTemplate requestTemplate = new RequestTemplate(); requestTemplate.feignTarget(target); - EnhancedFeignClient polarisFeignClient = new EnhancedFeignClient(delegate, new DefaultEnhancedPluginRunner(getMockEnhancedFeignPlugins())); + EnhancedFeignClient polarisFeignClient = new EnhancedFeignClient(delegate, new DefaultEnhancedPluginRunner(getMockEnhancedFeignPlugins(), null, sdkContext)); // 200 Response response = polarisFeignClient.execute(Request.create(Request.HttpMethod.GET, "http://localhost:8080/test", @@ -134,7 +139,7 @@ public class EnhancedFeignClientTest { enhancedPlugins.add(new EnhancedPlugin() { @Override public EnhancedPluginType getType() { - return EnhancedPluginType.PRE; + return EnhancedPluginType.Client.PRE; } @Override @@ -156,7 +161,7 @@ public class EnhancedFeignClientTest { enhancedPlugins.add(new EnhancedPlugin() { @Override public EnhancedPluginType getType() { - return EnhancedPluginType.POST; + return EnhancedPluginType.Client.POST; } @Override @@ -178,7 +183,7 @@ public class EnhancedFeignClientTest { enhancedPlugins.add(new EnhancedPlugin() { @Override public EnhancedPluginType getType() { - return EnhancedPluginType.EXCEPTION; + return EnhancedPluginType.Client.EXCEPTION; } @Override @@ -200,7 +205,7 @@ public class EnhancedFeignClientTest { enhancedPlugins.add(new EnhancedPlugin() { @Override public EnhancedPluginType getType() { - return EnhancedPluginType.FINALLY; + return EnhancedPluginType.Client.FINALLY; } @Override 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 index a516483f..0e982491 100644 --- 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 @@ -25,6 +25,9 @@ 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.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.client.api.SDKContext; import org.junit.jupiter.api.AfterAll; @@ -38,6 +41,7 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -65,6 +69,8 @@ public class EnhancedPluginContextTest { private SDKContext sdkContext; @Mock private ConsumerAPI consumerAPI; + @Mock + private Registration registration; @BeforeAll static void beforeAll() { @@ -111,24 +117,38 @@ public class EnhancedPluginContextTest { EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext(); enhancedPluginContext.setRequest(requestContext); enhancedPluginContext.setResponse(responseContext); - enhancedPluginContext.setServiceInstance(new DefaultServiceInstance()); + enhancedPluginContext.setTargetServiceInstance(new DefaultServiceInstance()); enhancedPluginContext.setThrowable(mock(Exception.class)); enhancedPluginContext.setDelay(0); assertThat(enhancedPluginContext.getRequest()).isNotNull(); assertThat(enhancedPluginContext.getResponse()).isNotNull(); - assertThat(enhancedPluginContext.getServiceInstance()).isNotNull(); + assertThat(enhancedPluginContext.getTargetServiceInstance()).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 enhancedPlugin = new SuccessPolarisReporter(reporterProperties, consumerAPI); + EnhancedPlugin enhancedPlugin1 = new ExceptionPolarisReporter(reporterProperties, consumerAPI); + EnhancedPluginRunner enhancedPluginRunner = new DefaultEnhancedPluginRunner(Arrays.asList(enhancedPlugin, enhancedPlugin1), registration, sdkContext); + enhancedPluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); + + assertThat(enhancedPluginRunner.getLocalServiceInstance()).isEqualTo(registration); 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); + doReturn(EnhancedPluginType.Client.POST).when(enhancedPlugin2).getType(); + + 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(); + + enhancedPluginRunner = new DefaultEnhancedPluginRunner(Arrays.asList(enhancedPlugin2), null, sdkContext); + enhancedPluginRunner.run(EnhancedPluginType.Client.POST, enhancedPluginContext); } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java index 21c61ef9..840c5d49 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/ExceptionPolarisReporterTest.java @@ -23,11 +23,7 @@ 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.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.client.api.SDKContext; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -40,6 +36,7 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.context.ApplicationContext; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -63,8 +60,6 @@ public class ExceptionPolarisReporterTest { private static MockedStatic mockedApplicationContextAwareUtils; @Mock private RpcEnhancementReporterProperties reporterProperties; - @Mock - private SDKContext sdkContext; @InjectMocks private ExceptionPolarisReporter exceptionPolarisReporter; @Mock @@ -75,6 +70,12 @@ public class ExceptionPolarisReporterTest { mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) .thenReturn("unit-test"); + ApplicationContext applicationContext = mock(ApplicationContext.class); + RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class); + doReturn(reporterProperties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); } @AfterAll @@ -95,7 +96,7 @@ public class ExceptionPolarisReporterTest { @Test public void testType() { - assertThat(exceptionPolarisReporter.getType()).isEqualTo(EnhancedPluginType.EXCEPTION); + assertThat(exceptionPolarisReporter.getType()).isEqualTo(EnhancedPluginType.Client.EXCEPTION); } @Test @@ -107,32 +108,23 @@ public class ExceptionPolarisReporterTest { doReturn(true).when(reporterProperties).isEnabled(); - 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(); - EnhancedPluginContext pluginContext = new EnhancedPluginContext(); EnhancedRequestContext request = EnhancedRequestContext.builder() .httpMethod(HttpMethod.GET) .url(URI.create("http://0.0.0.0/")) .httpHeaders(new HttpHeaders()) .build(); + request.toString(); EnhancedResponseContext response = EnhancedResponseContext.builder() .httpStatus(200) .build(); + response.toString(); DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); serviceInstance.setServiceId(SERVICE_PROVIDER); pluginContext.setRequest(request); pluginContext.setResponse(response); - pluginContext.setServiceInstance(serviceInstance); + pluginContext.setTargetServiceInstance(serviceInstance); pluginContext.setThrowable(new RuntimeException()); exceptionPolarisReporter.run(pluginContext); 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/plugin/PolarisEnhancedPluginUtilsTest.java similarity index 55% rename from spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/AbstractPolarisReporterAdapterTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/PolarisEnhancedPluginUtilsTest.java index 825da246..6b0006da 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/plugin/PolarisEnhancedPluginUtilsTest.java @@ -15,20 +15,19 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.rpc.enhancement; +package com.tencent.cloud.rpc.enhancement.plugin; import java.net.SocketTimeoutException; import java.net.URI; import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.HashMap; import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.constant.RouterConstant; 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.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.plugin.circuitbreaker.ResourceStat; import com.tencent.polaris.api.pojo.RetStatus; import com.tencent.polaris.api.rpc.ServiceCallResult; @@ -43,6 +42,7 @@ import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.context.ApplicationContext; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -54,12 +54,12 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; /** - * Test For {@link AbstractPolarisReporterAdapter}. + * Test For {@link PolarisEnhancedPluginUtils}. * * @author Elve.Xu 2022/7/11 */ @ExtendWith(MockitoExtension.class) -public class AbstractPolarisReporterAdapterTest { +public class PolarisEnhancedPluginUtilsTest { private static MockedStatic mockedApplicationContextAwareUtils; private final RpcEnhancementReporterProperties reporterProperties = new RpcEnhancementReporterProperties(); @@ -71,6 +71,12 @@ public class AbstractPolarisReporterAdapterTest { mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) .thenReturn("unit-test"); + ApplicationContext applicationContext = mock(ApplicationContext.class); + RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class); + doReturn(reporterProperties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); } @AfterAll @@ -86,25 +92,18 @@ public class AbstractPolarisReporterAdapterTest { @Test public void testServiceCallResult() 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(); - - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(reporterProperties, sdkContext); ServiceCallResult serviceCallResult; HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.add(RouterConstant.ROUTER_LABEL_HEADER, "{\"k1\":\"v1\"}"); - serviceCallResult = adapter.createServiceCallResult( + assertThat(PolarisEnhancedPluginUtils.getLabelMap(requestHeaders)).isEqualTo(new HashMap() {{ + put("k1", "v1"); + }}); + + serviceCallResult = PolarisEnhancedPluginUtils.createServiceCallResult( + "0.0.0.0", "test", null, null, @@ -117,7 +116,8 @@ public class AbstractPolarisReporterAdapterTest { ); assertThat(serviceCallResult.getRetStatus()).isEqualTo(RetStatus.RetSuccess); - serviceCallResult = adapter.createServiceCallResult( + serviceCallResult = PolarisEnhancedPluginUtils.createServiceCallResult( + "0.0.0.0", "test", null, null, @@ -130,7 +130,8 @@ public class AbstractPolarisReporterAdapterTest { ); assertThat(serviceCallResult.getRetStatus()).isEqualTo(RetStatus.RetFail); - serviceCallResult = adapter.createServiceCallResult( + serviceCallResult = PolarisEnhancedPluginUtils.createServiceCallResult( + "0.0.0.0", "test", null, null, @@ -143,7 +144,8 @@ public class AbstractPolarisReporterAdapterTest { ); assertThat(serviceCallResult.getRetStatus()).isEqualTo(RetStatus.RetTimeout); - serviceCallResult = adapter.createServiceCallResult( + serviceCallResult = PolarisEnhancedPluginUtils.createServiceCallResult( + "0.0.0.0", "test", "0.0.0.0", 8080, @@ -162,11 +164,9 @@ public class AbstractPolarisReporterAdapterTest { @Test public void testResourceStat() throws URISyntaxException { - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(reporterProperties, sdkContext); - ResourceStat resourceStat; - resourceStat = adapter.createInstanceResourceStat("test", + resourceStat = PolarisEnhancedPluginUtils.createInstanceResourceStat("test", null, null, new URI("http://0.0.0.0/"), @@ -176,7 +176,7 @@ public class AbstractPolarisReporterAdapterTest { ); assertThat(resourceStat.getRetStatus()).isEqualTo(RetStatus.RetSuccess); - resourceStat = adapter.createInstanceResourceStat("test", + resourceStat = PolarisEnhancedPluginUtils.createInstanceResourceStat("test", null, null, new URI("http://0.0.0.0/"), @@ -186,7 +186,7 @@ public class AbstractPolarisReporterAdapterTest { ); assertThat(resourceStat.getRetStatus()).isEqualTo(RetStatus.RetTimeout); - resourceStat = adapter.createInstanceResourceStat("test", + resourceStat = PolarisEnhancedPluginUtils.createInstanceResourceStat("test", null, null, new URI("http://0.0.0.0/"), @@ -200,13 +200,32 @@ public class AbstractPolarisReporterAdapterTest { @Test public void testApplyWithDefaultConfig() { RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); - // Mock Condition - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); + ApplicationContext applicationContext = mock(ApplicationContext.class); + doReturn(properties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); + // Assert + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.OK)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); + } + + @Test + public void testApplyWithHttpStatus() { + RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); + properties.setStatuses(Arrays.asList(HttpStatus.BAD_GATEWAY, HttpStatus.INTERNAL_SERVER_ERROR)); + ApplicationContext applicationContext = mock(ApplicationContext.class); + doReturn(properties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); // Assert - assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(null)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.OK)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); } @Test @@ -216,12 +235,16 @@ public class AbstractPolarisReporterAdapterTest { properties.getStatuses().clear(); properties.setIgnoreInternalServerError(false); - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); + ApplicationContext applicationContext = mock(ApplicationContext.class); + doReturn(properties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); // Assert - assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(true); - assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.OK)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); } @Test @@ -231,12 +254,16 @@ public class AbstractPolarisReporterAdapterTest { properties.getStatuses().clear(); properties.setIgnoreInternalServerError(true); - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); + ApplicationContext applicationContext = mock(ApplicationContext.class); + doReturn(properties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); // Assert - assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.OK)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); } @Test @@ -246,12 +273,16 @@ public class AbstractPolarisReporterAdapterTest { properties.getStatuses().clear(); properties.getSeries().clear(); - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); + ApplicationContext applicationContext = mock(ApplicationContext.class); + doReturn(properties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); // Assert - assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.OK)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(true); } @Test @@ -262,65 +293,46 @@ public class AbstractPolarisReporterAdapterTest { properties.getSeries().clear(); properties.getSeries().add(HttpStatus.Series.CLIENT_ERROR); - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); + ApplicationContext applicationContext = mock(ApplicationContext.class); + doReturn(properties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); // Assert - assertThat(adapter.apply(HttpStatus.OK)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(false); - assertThat(adapter.apply(HttpStatus.FORBIDDEN)).isEqualTo(true); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.OK)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.INTERNAL_SERVER_ERROR)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.BAD_GATEWAY)).isEqualTo(false); + assertThat(PolarisEnhancedPluginUtils.apply(HttpStatus.FORBIDDEN)).isEqualTo(true); } @Test public void testGetRetStatusFromRequest() { - RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); - // Mock Condition - properties.getStatuses().clear(); - properties.getSeries().clear(); - properties.getSeries().add(HttpStatus.Series.CLIENT_ERROR); - - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); HttpHeaders headers = new HttpHeaders(); - RetStatus ret = adapter.getRetStatusFromRequest(headers, RetStatus.RetFail); + RetStatus ret = PolarisEnhancedPluginUtils.getRetStatusFromRequest(headers, RetStatus.RetFail); assertThat(ret).isEqualTo(RetStatus.RetFail); headers.set(HeaderConstant.INTERNAL_CALLEE_RET_STATUS, RetStatus.RetFlowControl.getDesc()); - ret = adapter.getRetStatusFromRequest(headers, RetStatus.RetFail); + ret = PolarisEnhancedPluginUtils.getRetStatusFromRequest(headers, RetStatus.RetFail); assertThat(ret).isEqualTo(RetStatus.RetFlowControl); headers.set(HeaderConstant.INTERNAL_CALLEE_RET_STATUS, RetStatus.RetReject.getDesc()); - ret = adapter.getRetStatusFromRequest(headers, RetStatus.RetFail); + ret = PolarisEnhancedPluginUtils.getRetStatusFromRequest(headers, RetStatus.RetFail); assertThat(ret).isEqualTo(RetStatus.RetReject); } @Test public void testGetActiveRuleNameFromRequest() { - RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); - // Mock Condition - properties.getStatuses().clear(); - properties.getSeries().clear(); - properties.getSeries().add(HttpStatus.Series.CLIENT_ERROR); - - SimplePolarisReporterAdapter adapter = new SimplePolarisReporterAdapter(properties, sdkContext); HttpHeaders headers = new HttpHeaders(); - String ruleName = adapter.getActiveRuleNameFromRequest(headers); + String ruleName = PolarisEnhancedPluginUtils.getActiveRuleNameFromRequest(headers); assertThat(ruleName).isEqualTo(""); headers.set(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, "mock_rule"); - ruleName = adapter.getActiveRuleNameFromRequest(headers); + ruleName = PolarisEnhancedPluginUtils.getActiveRuleNameFromRequest(headers); assertThat(ruleName).isEqualTo("mock_rule"); } - /** - * Simple Polaris CircuitBreak Adapter Implements . - */ - public static class SimplePolarisReporterAdapter extends AbstractPolarisReporterAdapter { - - protected SimplePolarisReporterAdapter(RpcEnhancementReporterProperties reportProperties, SDKContext context) { - super(reportProperties, context); - } - } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java index 9af4ca01..5af25a89 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/plugin/SuccessPolarisReporterTest.java @@ -23,11 +23,7 @@ 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.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.client.api.SDKContext; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -40,6 +36,7 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.context.ApplicationContext; import org.springframework.http.HttpMethod; import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; @@ -60,8 +57,6 @@ import static org.mockito.Mockito.verify; public class SuccessPolarisReporterTest { private static MockedStatic mockedApplicationContextAwareUtils; @Mock - private SDKContext sdkContext; - @Mock private RpcEnhancementReporterProperties reporterProperties; @InjectMocks private SuccessPolarisReporter successPolarisReporter; @@ -73,6 +68,12 @@ public class SuccessPolarisReporterTest { mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) .thenReturn("unit-test"); + ApplicationContext applicationContext = mock(ApplicationContext.class); + RpcEnhancementReporterProperties reporterProperties = mock(RpcEnhancementReporterProperties.class); + doReturn(reporterProperties) + .when(applicationContext).getBean(RpcEnhancementReporterProperties.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext) + .thenReturn(applicationContext); } @AfterAll @@ -93,7 +94,7 @@ public class SuccessPolarisReporterTest { @Test public void testType() { - assertThat(successPolarisReporter.getType()).isEqualTo(EnhancedPluginType.POST); + assertThat(successPolarisReporter.getType()).isEqualTo(EnhancedPluginType.Client.POST); } @Test @@ -105,31 +106,23 @@ public class SuccessPolarisReporterTest { verify(context, times(0)).getRequest(); doReturn(true).when(reporterProperties).isEnabled(); - 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(); EnhancedPluginContext pluginContext = new EnhancedPluginContext(); EnhancedRequestContext request = EnhancedRequestContext.builder() .httpMethod(HttpMethod.GET) .url(URI.create("http://0.0.0.0/")) .build(); + request.toString(); EnhancedResponseContext response = EnhancedResponseContext.builder() .httpStatus(200) .build(); + response.toString(); DefaultServiceInstance serviceInstance = new DefaultServiceInstance(); serviceInstance.setServiceId(SERVICE_PROVIDER); pluginContext.setRequest(request); pluginContext.setResponse(response); - pluginContext.setServiceInstance(serviceInstance); + pluginContext.setTargetServiceInstance(serviceInstance); successPolarisReporter.run(pluginContext); successPolarisReporter.getOrder(); diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptorTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptorTest.java index 6b256f01..10bcbab6 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptorTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateInterceptorTest.java @@ -40,6 +40,7 @@ import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -65,6 +66,8 @@ public class EnhancedRestTemplateInterceptorTest { @Mock private SDKContext sdkContext; @Mock + Registration registration; + @Mock private ClientHttpRequestExecution mockClientHttpRequestExecution; @Mock private ClientHttpResponse mockClientHttpResponse; @@ -109,7 +112,7 @@ public class EnhancedRestTemplateInterceptorTest { doReturn(mockHttpHeaders).when(mockHttpRequest).getHeaders(); doReturn(mockClientHttpResponse).when(mockClientHttpRequestExecution).execute(mockHttpRequest, inputBody); - EnhancedRestTemplateInterceptor reporter = new EnhancedRestTemplateInterceptor(new DefaultEnhancedPluginRunner(new ArrayList<>())); + EnhancedRestTemplateInterceptor reporter = new EnhancedRestTemplateInterceptor(new DefaultEnhancedPluginRunner(new ArrayList<>(), registration, null)); 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/resttemplate/BlockingLoadBalancerClientAspectTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisLoadBalancerRequestTransformerTest.java similarity index 79% rename from spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspectTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisLoadBalancerRequestTransformerTest.java index 82bf173b..4ae6084a 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspectTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/PolarisLoadBalancerRequestTransformerTest.java @@ -17,13 +17,11 @@ package com.tencent.cloud.rpc.enhancement.resttemplate; -import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.util.ApplicationContextAwareUtils; -import org.aspectj.lang.ProceedingJoinPoint; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -36,7 +34,9 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.cloud.client.ServiceInstance; import org.springframework.context.ApplicationContext; +import org.springframework.http.HttpRequest; +import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE; 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; @@ -45,13 +45,16 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @ExtendWith(MockitoExtension.class) -public class BlockingLoadBalancerClientAspectTest { - +public class PolarisLoadBalancerRequestTransformerTest { private static MockedStatic mockedApplicationContextAwareUtils; + + private PolarisLoadBalancerRequestTransformer transformer = new PolarisLoadBalancerRequestTransformer(); + @Mock - private ProceedingJoinPoint proceedingJoinPoint; + private HttpRequest clientRequest; - private BlockingLoadBalancerClientAspect aspect = new BlockingLoadBalancerClientAspect(); + @Mock + private ServiceInstance serviceInstance; @BeforeAll static void beforeAll() { @@ -79,14 +82,8 @@ public class BlockingLoadBalancerClientAspectTest { @Test public void test() throws Throwable { - ServiceInstance serviceInstance = mock(ServiceInstance.class); - doReturn("0.0.0.0").when(serviceInstance).getHost(); - doReturn(80).when(serviceInstance).getPort(); - doReturn(new Object[]{ serviceInstance }).when(proceedingJoinPoint).getArgs(); - aspect.invoke(proceedingJoinPoint); - aspect.pointcut(); - assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST)).isEqualTo("0.0.0.0"); - assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT)).isEqualTo("80"); + transformer.transformRequest(clientRequest, serviceInstance); + assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(LOAD_BALANCER_SERVICE_INSTANCE)).isEqualTo(serviceInstance); } - } + diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java index 69867c6a..39706816 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/scg/EnhancedGatewayGlobalFilterTest.java @@ -39,6 +39,7 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import reactor.core.publisher.Mono; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.route.Route; import org.springframework.context.ApplicationContext; @@ -62,6 +63,8 @@ public class EnhancedGatewayGlobalFilterTest { private static MockedStatic mockedApplicationContextAwareUtils; @Mock + Registration registration; + @Mock ServerWebExchange exchange; @Mock GatewayFilterChain chain; @@ -115,7 +118,7 @@ public class EnhancedGatewayGlobalFilterTest { doReturn(request).when(exchange).getRequest(); doReturn(response).when(exchange).getResponse(); - EnhancedGatewayGlobalFilter reporter = new EnhancedGatewayGlobalFilter(new DefaultEnhancedPluginRunner(new ArrayList<>())); + EnhancedGatewayGlobalFilter reporter = new EnhancedGatewayGlobalFilter(new DefaultEnhancedPluginRunner(new ArrayList<>(), registration, null)); reporter.getOrder(); reporter.filter(exchange, chain).block(); 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/EnhancedWebClientExchangeFilterFunctionTest.java similarity index 91% rename from spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientExchangeFilterFunctionTest.java index f8a4a673..4801e4cb 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/EnhancedWebClientExchangeFilterFunctionTest.java @@ -39,9 +39,11 @@ import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import reactor.core.publisher.Mono; +import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.ExchangeFunction; @@ -56,7 +58,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @ExtendWith(MockitoExtension.class) -public class EnhancedWebClientReporterTest { +public class EnhancedWebClientExchangeFilterFunctionTest { private static MockedStatic mockedApplicationContextAwareUtils; @Mock @@ -64,6 +66,8 @@ public class EnhancedWebClientReporterTest { @Mock private SDKContext sdkContext; @Mock + private Registration registration; + @Mock private ClientRequest clientRequest; @Mock private ExchangeFunction exchangeFunction; @@ -101,9 +105,10 @@ public class EnhancedWebClientReporterTest { doReturn(HttpMethod.GET).when(clientRequest).method(); ClientResponse.Headers headers = mock(ClientResponse.Headers.class); doReturn(headers).when(clientResponse).headers(); + doReturn(HttpStatus.valueOf(200)).when(clientResponse).statusCode(); doReturn(Mono.just(clientResponse)).when(exchangeFunction).exchange(any()); - EnhancedWebClientReporter reporter = new EnhancedWebClientReporter(new DefaultEnhancedPluginRunner(new ArrayList<>())); + EnhancedWebClientExchangeFilterFunction reporter = new EnhancedWebClientExchangeFilterFunction(new DefaultEnhancedPluginRunner(new ArrayList<>(), registration, null)); ClientResponse clientResponse1 = reporter.filter(clientRequest, exchangeFunction).block(); assertThat(clientResponse1).isEqualTo(clientResponse); diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java index 811b7c5e..7b7c4e0d 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java @@ -17,7 +17,6 @@ package com.tencent.cloud.rpc.enhancement.webclient; -import com.tencent.cloud.common.constant.HeaderConstant; import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.common.metadata.StaticMetadataManager; @@ -37,6 +36,7 @@ import org.springframework.cloud.client.ServiceInstance; import org.springframework.context.ApplicationContext; import org.springframework.web.reactive.function.client.ClientRequest; +import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE; 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; @@ -83,8 +83,7 @@ public class PolarisLoadBalancerClientRequestTransformerTest { @Test public void test() throws Throwable { - doReturn("test").when(serviceInstance).getServiceId(); transformer.transformRequest(clientRequest, serviceInstance); - assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID)).isEqualTo("test"); + assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(LOAD_BALANCER_SERVICE_INSTANCE)).isEqualTo(serviceInstance); } }