fix feign rpc client

pull/994/head
seanyu 2 years ago
parent 33980d3101
commit 8817344d9c

@ -24,7 +24,7 @@ import com.tencent.cloud.common.pojo.PolarisServiceInstance;
import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled;
import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignBeanPostProcessor; import com.tencent.cloud.rpc.enhancement.feign.EnhancedFeignBeanPostProcessor;
import com.tencent.cloud.rpc.enhancement.feign.PolarisLoadBalancerFeignRequestTransformer; import com.tencent.cloud.rpc.enhancement.feign.EnhancedLoadBalancerClientAspect;
import com.tencent.cloud.rpc.enhancement.filter.EnhancedReactiveFilter; import com.tencent.cloud.rpc.enhancement.filter.EnhancedReactiveFilter;
import com.tencent.cloud.rpc.enhancement.filter.EnhancedServletFilter; import com.tencent.cloud.rpc.enhancement.filter.EnhancedServletFilter;
import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner; import com.tencent.cloud.rpc.enhancement.plugin.DefaultEnhancedPluginRunner;
@ -70,11 +70,11 @@ import org.springframework.core.annotation.Order;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
import static jakarta.servlet.DispatcherType.ASYNC; import static javax.servlet.DispatcherType.ASYNC;
import static jakarta.servlet.DispatcherType.ERROR; import static javax.servlet.DispatcherType.ERROR;
import static jakarta.servlet.DispatcherType.FORWARD; import static javax.servlet.DispatcherType.FORWARD;
import static jakarta.servlet.DispatcherType.INCLUDE; import static javax.servlet.DispatcherType.INCLUDE;
import static jakarta.servlet.DispatcherType.REQUEST; import static javax.servlet.DispatcherType.REQUEST;
/** /**
* Auto Configuration for Polaris {@link feign.Feign} OR {@link RestTemplate} which can automatically bring in the call * Auto Configuration for Polaris {@link feign.Feign} OR {@link RestTemplate} which can automatically bring in the call
@ -197,9 +197,9 @@ public class RpcEnhancementAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ConditionalOnClass(name = {"org.springframework.cloud.openfeign.loadbalancer.LoadBalancerFeignRequestTransformer"}) @ConditionalOnClass(name = "org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser")
public PolarisLoadBalancerFeignRequestTransformer polarisLoadBalancerFeignRequestTransformer() { public EnhancedLoadBalancerClientAspect enhancedLoadBalancerClientAspect() {
return new PolarisLoadBalancerFeignRequestTransformer(); return new EnhancedLoadBalancerClientAspect();
} }
} }

@ -28,7 +28,6 @@ import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient;
import org.springframework.cloud.openfeign.loadbalancer.LoadBalancerFeignRequestTransformer;
import org.springframework.cloud.openfeign.loadbalancer.RetryableFeignBlockingLoadBalancerClient; import org.springframework.cloud.openfeign.loadbalancer.RetryableFeignBlockingLoadBalancerClient;
import org.springframework.lang.NonNull; import org.springframework.lang.NonNull;

@ -17,15 +17,12 @@
package com.tencent.cloud.rpc.enhancement.feign; package com.tencent.cloud.rpc.enhancement.feign;
import java.util.List;
import feign.Client; import feign.Client;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient;
import org.springframework.cloud.openfeign.loadbalancer.LoadBalancerFeignRequestTransformer;
/** /**
* Wrap for {@link FeignBlockingLoadBalancerClient}. * Wrap for {@link FeignBlockingLoadBalancerClient}.

@ -18,32 +18,32 @@
package com.tencent.cloud.rpc.enhancement.feign; package com.tencent.cloud.rpc.enhancement.feign;
import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.common.metadata.MetadataContextHolder;
import feign.Request; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.springframework.cloud.client.ServiceInstance; import org.aspectj.lang.annotation.Aspect;
import org.springframework.cloud.openfeign.loadbalancer.LoadBalancerFeignRequestTransformer; import org.aspectj.lang.annotation.Pointcut;
import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE; import static com.tencent.cloud.rpc.enhancement.resttemplate.PolarisLoadBalancerRequestTransformer.LOAD_BALANCER_SERVICE_INSTANCE;
/** /**
* PolarisLoadBalancerFeignRequestTransformer. * EnhancedLoadBalancerClientAspect.
* *
* @author sean yu * @author sean yu
*/ */
public class PolarisLoadBalancerFeignRequestTransformer implements LoadBalancerFeignRequestTransformer { @Aspect
public class EnhancedLoadBalancerClientAspect {
@Pointcut("execution(public * org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser.choose(..)) ")
public void pointcut() {
/**
* Transform Request, add Loadbalancer ServiceInstance to MetadataContext.
* @param request request
* @param instance instance
* @return HttpRequest
*/
@Override
public Request transformRequest(Request request, ServiceInstance instance) {
if (instance != null) {
MetadataContextHolder.get().setLoadbalancer(LOAD_BALANCER_SERVICE_INSTANCE, instance);
}
return request;
} }
@Around("pointcut()")
public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = joinPoint.proceed();
if (result != null) {
MetadataContextHolder.get().setLoadbalancer(LOAD_BALANCER_SERVICE_INSTANCE, result);
}
return result;
}
} }

@ -24,16 +24,17 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; 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.common.constant.MetadataConstant;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedResponseContext;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;

@ -25,6 +25,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
import com.google.common.net.HttpHeaders; import com.google.common.net.HttpHeaders;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedRequestContext;
@ -58,7 +59,7 @@ public class AssemblyRequestContext implements RequestContext {
.orElse(new ArrayList<>()) .orElse(new ArrayList<>())
.stream() .stream()
.flatMap(it -> Arrays.stream(it.split(";"))) .flatMap(it -> Arrays.stream(it.split(";")))
.toList(); .collect(Collectors.toList());
allCookies.forEach(cookie -> { allCookies.forEach(cookie -> {
String[] cookieKV = cookie.split("="); String[] cookieKV = cookie.split("=");
if (cookieKV.length == 2) { if (cookieKV.length == 2) {

@ -22,12 +22,10 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient;
import org.springframework.cloud.openfeign.loadbalancer.LoadBalancerFeignRequestTransformer;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
@ -65,9 +63,6 @@ public class EnhancedFeignBeanPostProcessorTest {
} }
return null; return null;
}).when(beanFactory).getBean(any(Class.class)); }).when(beanFactory).getBean(any(Class.class));
ObjectProvider objectProvider = mock(ObjectProvider.class);
doReturn(new PolarisLoadBalancerFeignRequestTransformer()).when(objectProvider).getObject();
doReturn(objectProvider).when(beanFactory).getBeanProvider(LoadBalancerFeignRequestTransformer.class);
enhancedFeignBeanPostProcessor.setBeanFactory(beanFactory); enhancedFeignBeanPostProcessor.setBeanFactory(beanFactory);
// isNeedWrap(bean) == false // isNeedWrap(bean) == false

@ -30,6 +30,6 @@ public class EnhancedFeignBlockingLoadBalancerClientTest {
@Test @Test
public void testConstructor() { public void testConstructor() {
assertThatCode(() -> new EnhancedFeignBlockingLoadBalancerClient(null, null, null, null)).doesNotThrowAnyException(); assertThatCode(() -> new EnhancedFeignBlockingLoadBalancerClient(null, null, null)).doesNotThrowAnyException();
} }
} }

@ -22,7 +22,7 @@ import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.metadata.StaticMetadataManager;
import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import feign.Request; import org.aspectj.lang.ProceedingJoinPoint;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@ -45,22 +45,18 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
/** /**
* PolarisLoadBalancerFeignRequestTransformerTest. * EnhancedLoadBalancerClientAspectTest.
* *
* @author sean yu * @author sean yu
*/ */
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
public class PolarisLoadBalancerFeignRequestTransformerTest { public class EnhancedLoadBalancerClientAspectTest {
private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils; private static MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils;
private PolarisLoadBalancerFeignRequestTransformer transformer = new PolarisLoadBalancerFeignRequestTransformer();
@Mock @Mock
private Request clientRequest; private ProceedingJoinPoint proceedingJoinPoint;
@Mock private EnhancedLoadBalancerClientAspect aspect = new EnhancedLoadBalancerClientAspect();
private ServiceInstance serviceInstance;
@BeforeAll @BeforeAll
static void beforeAll() { static void beforeAll() {
@ -88,7 +84,10 @@ public class PolarisLoadBalancerFeignRequestTransformerTest {
@Test @Test
public void test() throws Throwable { public void test() throws Throwable {
transformer.transformRequest(clientRequest, serviceInstance); ServiceInstance serviceInstance = mock(ServiceInstance.class);
doReturn(serviceInstance).when(proceedingJoinPoint).proceed();
aspect.invoke(proceedingJoinPoint);
aspect.pointcut();
assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(LOAD_BALANCER_SERVICE_INSTANCE)).isEqualTo(serviceInstance); assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(LOAD_BALANCER_SERVICE_INSTANCE)).isEqualTo(serviceInstance);
} }
} }

@ -43,7 +43,7 @@ public class AssemblyMetadataProviderTest {
@Test @Test
public void testAssemblyMetadataProvider() { public void testAssemblyMetadataProvider() {
ServiceInstance serviceInstance = Mockito.mock(ServiceInstance.class); ServiceInstance serviceInstance = Mockito.mock(ServiceInstance.class);
Map<String, String> metadata = new HashMap<>() {{ Map<String, String> metadata = new HashMap<String, String>() {{
put("k", "v"); put("k", "v");
}}; }};
doReturn(metadata).when(serviceInstance).getMetadata(); doReturn(metadata).when(serviceInstance).getMetadata();

@ -18,8 +18,8 @@
package com.tencent.cloud.rpc.enhancement.plugin; package com.tencent.cloud.rpc.enhancement.plugin;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
@ -86,7 +86,7 @@ public class AssemblyResponseContextTest {
assertThat(assemblyResponseContext.getRetCode()).isEqualTo(HttpStatus.OK.value()); assertThat(assemblyResponseContext.getRetCode()).isEqualTo(HttpStatus.OK.value());
assertThat(assemblyResponseContext.getThrowable()).isEqualTo(null); assertThat(assemblyResponseContext.getThrowable()).isEqualTo(null);
assertThat(assemblyResponseContext.getRetStatus()).isEqualTo(RetStatus.RetSuccess); assertThat(assemblyResponseContext.getRetStatus()).isEqualTo(RetStatus.RetSuccess);
assertThat(assemblyResponseContext.listHeaders()).isEqualTo(new HashSet<>(List.of("a"))); assertThat(assemblyResponseContext.listHeaders()).isEqualTo(new HashSet<>(Arrays.asList("a")));
Throwable e = new SocketTimeoutException(); Throwable e = new SocketTimeoutException();
assemblyResponseContext = new AssemblyResponseContext(null, e); assemblyResponseContext = new AssemblyResponseContext(null, e);

@ -43,7 +43,7 @@ import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatusCode; import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.ExchangeFunction; import org.springframework.web.reactive.function.client.ExchangeFunction;
@ -105,7 +105,7 @@ public class EnhancedWebClientExchangeFilterFunctionTest {
doReturn(HttpMethod.GET).when(clientRequest).method(); doReturn(HttpMethod.GET).when(clientRequest).method();
ClientResponse.Headers headers = mock(ClientResponse.Headers.class); ClientResponse.Headers headers = mock(ClientResponse.Headers.class);
doReturn(headers).when(clientResponse).headers(); doReturn(headers).when(clientResponse).headers();
doReturn(HttpStatusCode.valueOf(200)).when(clientResponse).statusCode(); doReturn(HttpStatus.valueOf(200)).when(clientResponse).statusCode();
doReturn(Mono.just(clientResponse)).when(exchangeFunction).exchange(any()); doReturn(Mono.just(clientResponse)).when(exchangeFunction).exchange(any());
EnhancedWebClientExchangeFilterFunction reporter = new EnhancedWebClientExchangeFilterFunction(new DefaultEnhancedPluginRunner(new ArrayList<>(), registration, null)); EnhancedWebClientExchangeFilterFunction reporter = new EnhancedWebClientExchangeFilterFunction(new DefaultEnhancedPluginRunner(new ArrayList<>(), registration, null));

Loading…
Cancel
Save