Fix issue 579:Report the labels in request when report the result of invocation by RestTemplate (#600)

pull/605/head
Wu Daifu 2 years ago committed by GitHub
parent c379318377
commit e0086e44cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -2,3 +2,4 @@
---
- [Optimize: remove discovery module useless code](https://github.com/Tencent/spring-cloud-tencent/pull/597)
- [Fix issue 579:Report the labels in request when report the result of invocation by RestTemplate](https://github.com/Tencent/spring-cloud-tencent/pull/600)

@ -32,6 +32,7 @@ import com.netflix.loadbalancer.RoundRobinRule;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.WeightedResponseTimeRule;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.pojo.PolarisServer;
import com.tencent.cloud.polaris.loadbalancer.LoadBalancerUtils;

@ -28,11 +28,11 @@ import java.util.Optional;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.reactive.LoadBalancerCommand;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import com.tencent.cloud.common.constant.RouterConstants;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer;

@ -21,7 +21,7 @@ package com.tencent.cloud.polaris.router.interceptor;
import java.util.Map;
import java.util.Set;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import com.tencent.cloud.polaris.router.config.properties.PolarisMetadataRouterProperties;
import com.tencent.cloud.polaris.router.spi.RouterRequestInterceptor;
import com.tencent.polaris.plugins.router.metadata.MetadataRouter;

@ -21,7 +21,7 @@ package com.tencent.cloud.polaris.router.interceptor;
import java.util.HashMap;
import java.util.Map;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import com.tencent.cloud.polaris.router.config.properties.PolarisNearByRouterProperties;
import com.tencent.cloud.polaris.router.spi.RouterRequestInterceptor;
import com.tencent.polaris.plugins.router.nearby.NearbyRouter;

@ -21,7 +21,7 @@ package com.tencent.cloud.polaris.router.interceptor;
import java.util.HashMap;
import java.util.Map;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import com.tencent.cloud.polaris.router.config.properties.PolarisRuleBasedRouterProperties;
import com.tencent.cloud.polaris.router.spi.RouterRequestInterceptor;
import com.tencent.polaris.plugins.router.rule.RuleBasedRouter;

@ -19,7 +19,9 @@
package com.tencent.cloud.polaris.router.resttemplate;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@ -27,11 +29,12 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import com.tencent.cloud.common.constant.PolarisRouterContext;
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.util.JacksonUtils;
import com.tencent.cloud.common.util.expresstion.SpringWebExpressionLabelUtils;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver;
import org.slf4j.Logger;
@ -48,6 +51,8 @@ import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
/**
* PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor capabilities.
* Parses the label from the request and puts it into the RouterContext for routing.
@ -96,9 +101,20 @@ public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor {
if (isRibbonLoadBalanceClient) {
PolarisRouterContext routerContext = genRouterContext(request, body, peerServiceName);
return ((RibbonLoadBalancerClient) loadBalancer).execute(peerServiceName,
ClientHttpResponse response = ((RibbonLoadBalancerClient) loadBalancer).execute(peerServiceName,
this.requestFactory.createRequest(request, body, execution), routerContext);
Map<String, String> labels = routerContext.getLabels(PolarisRouterContext.ROUTER_LABELS);
// put labels in header
String encodedLabelsContent;
try {
encodedLabelsContent = URLEncoder.encode(JacksonUtils.serialize2Json(labels), UTF_8);
}
catch (UnsupportedEncodingException e) {
throw new RuntimeException("unsupported charset exception " + UTF_8);
}
response.getHeaders().add(PolarisRouterContext.ROUTER_LABELS, encodedLabelsContent);
return response;
}
return this.loadBalancer.execute(peerServiceName,

@ -26,11 +26,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import com.tencent.cloud.common.constant.PolarisRouterContext;
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.util.expresstion.SpringWebExpressionLabelUtils;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver;
import org.slf4j.Logger;

@ -18,7 +18,7 @@
package com.tencent.cloud.polaris.router.spi;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import com.tencent.polaris.router.api.rpc.ProcessRoutersRequest;
/**

@ -18,7 +18,7 @@
package com.tencent.cloud.polaris.router.spi;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import com.tencent.polaris.router.api.rpc.ProcessRoutersResponse;
/**

@ -29,12 +29,12 @@ import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import com.netflix.zuul.context.RequestContext;
import com.tencent.cloud.common.constant.PolarisRouterContext;
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.util.BeanFactoryUtils;
import com.tencent.cloud.common.util.expresstion.ServletExpressionLabelUtils;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.spi.ServletRouterLabelResolver;
import org.slf4j.Logger;

@ -35,6 +35,7 @@ import com.netflix.loadbalancer.RetryRule;
import com.netflix.loadbalancer.RoundRobinRule;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.WeightedResponseTimeRule;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.pojo.PolarisServer;

@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Set;
import com.google.common.collect.Sets;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import org.junit.Assert;
import org.junit.Test;

@ -26,12 +26,12 @@ import java.util.Map;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.loadbalancer.ILoadBalancer;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import com.tencent.cloud.common.constant.RouterConstants;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.polaris.router.SimpleLoadBalancer;
import org.junit.Assert;
import org.junit.Test;

@ -19,20 +19,25 @@
package com.tencent.cloud.polaris.router.resttemplate;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.tencent.cloud.common.constant.PolarisRouterContext;
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.util.ApplicationContextAwareUtils;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.common.util.expresstion.SpringWebExpressionLabelUtils;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver;
import org.assertj.core.api.Assertions;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -53,7 +58,10 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.mock.http.client.MockClientHttpResponse;
import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ -82,23 +90,27 @@ public class PolarisLoadBalancerInterceptorTest {
String calleeService = "calleeService";
HttpRequest request = new MockedHttpRequest("http://" + calleeService + "/user/get");
Map<String, String> routerLabels = new HashMap<>();
// mock local metadata
Map<String, String> localMetadata = new HashMap<>();
localMetadata.put("k1", "v1");
localMetadata.put("k2", "v2");
when(staticMetadataManager.getMergedStaticMetadata()).thenReturn(localMetadata);
routerLabels.putAll(localMetadata);
// mock expression rule labels
Set<String> expressionKeys = new HashSet<>();
expressionKeys.add("${http.method}");
expressionKeys.add("${http.uri}");
when(routerRuleLabelResolver.getExpressionLabelKeys(callerService, callerService, calleeService)).thenReturn(expressionKeys);
routerLabels.putAll(SpringWebExpressionLabelUtils.resolve(request, expressionKeys));
// mock custom resolved from request
Map<String, String> customResolvedLabels = new HashMap<>();
customResolvedLabels.put("k3", "v3");
customResolvedLabels.put("k4", "v4");
when(routerLabelResolver.resolve(request, null, expressionKeys)).thenReturn(customResolvedLabels);
routerLabels.putAll(customResolvedLabels);
try (MockedStatic<ApplicationContextAwareUtils> mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class)) {
@ -112,6 +124,7 @@ public class PolarisLoadBalancerInterceptorTest {
transitiveLabels.put("k1", "v1");
transitiveLabels.put("k2", "v22");
when(metadataContext.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE)).thenReturn(transitiveLabels);
routerLabels.putAll(transitiveLabels);
try (MockedStatic<MetadataContextHolder> mockedMetadataContextHolder = Mockito.mockStatic(MetadataContextHolder.class)) {
mockedMetadataContextHolder.when(MetadataContextHolder::get).thenReturn(metadataContext);
@ -122,11 +135,22 @@ public class PolarisLoadBalancerInterceptorTest {
PolarisLoadBalancerInterceptor polarisLoadBalancerInterceptor = new PolarisLoadBalancerInterceptor(loadBalancerClient,
loadBalancerRequestFactory, Collections.singletonList(routerLabelResolver), staticMetadataManager, routerRuleLabelResolver);
ClientHttpResponse mockedResponse = new MockClientHttpResponse(new byte[] {}, HttpStatus.OK);
when(loadBalancerClient.execute(eq(calleeService), eq(loadBalancerRequest), any(PolarisRouterContext.class))).thenReturn(mockedResponse);
polarisLoadBalancerInterceptor.intercept(request, null, null);
verify(staticMetadataManager).getMergedStaticMetadata();
verify(routerRuleLabelResolver).getExpressionLabelKeys(callerService, callerService, calleeService);
verify(routerLabelResolver).resolve(request, null, expressionKeys);
String encodedLabelsContent;
try {
encodedLabelsContent = URLEncoder.encode(JacksonUtils.serialize2Json(routerLabels), UTF_8);
}
catch (UnsupportedEncodingException e) {
throw new RuntimeException("unsupported charset exception " + UTF_8);
}
Assertions.assertThat(mockedResponse.getHeaders().get(PolarisRouterContext.ROUTER_LABELS).get(0)).isEqualTo(encodedLabelsContent);
}
}
}

@ -25,11 +25,11 @@ import java.util.Set;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.tencent.cloud.common.constant.PolarisRouterContext;
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.util.ApplicationContextAwareUtils;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.spi.SpringWebRouterLabelResolver;
import org.junit.AfterClass;

@ -29,12 +29,12 @@ import com.netflix.client.config.IClientConfig;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.niws.client.http.RestClient;
import com.netflix.zuul.context.RequestContext;
import com.tencent.cloud.common.constant.PolarisRouterContext;
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.util.ApplicationContextAwareUtils;
import com.tencent.cloud.polaris.loadbalancer.PolarisLoadBalancer;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
import com.tencent.cloud.polaris.router.spi.ServletRouterLabelResolver;
import okhttp3.OkHttpClient;

@ -16,7 +16,7 @@
*
*/
package com.tencent.cloud.polaris.router;
package com.tencent.cloud.common.constant;
import java.util.Arrays;
import java.util.Collections;

@ -21,7 +21,7 @@ package com.tencent.cloud.plugin.featureenv;
import java.util.HashMap;
import java.util.Map;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import com.tencent.cloud.polaris.router.spi.RouterRequestInterceptor;
import com.tencent.polaris.api.rpc.MetadataFailoverType;
import com.tencent.polaris.plugins.router.metadata.MetadataRouter;

@ -22,7 +22,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import com.tencent.polaris.api.pojo.DefaultServiceInstances;
import com.tencent.polaris.api.pojo.ServiceInstances;
import com.tencent.polaris.api.pojo.ServiceKey;

@ -18,9 +18,13 @@
package com.tencent.cloud.rpc.enhancement.resttemplate;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.rpc.enhancement.AbstractPolarisReporterAdapter;
@ -29,6 +33,7 @@ import com.tencent.polaris.api.core.ConsumerAPI;
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 org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -41,6 +46,8 @@ import org.springframework.http.client.ClientHttpResponse;
import org.springframework.lang.NonNull;
import org.springframework.web.client.ResponseErrorHandler;
import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
/**
* Extend ResponseErrorHandler to get request information.
*
@ -129,6 +136,18 @@ public class EnhancedRestTemplateReporter extends AbstractPolarisReporterAdapter
resultRequest.setRetStatus(RetStatus.RetFail);
}
List<String> labels = response.getHeaders().get(PolarisRouterContext.ROUTER_LABELS);
if (CollectionUtils.isNotEmpty(labels)) {
String label = labels.get(0);
try {
label = URLDecoder.decode(label, UTF_8);
}
catch (UnsupportedEncodingException e) {
LOGGER.error("unsupported charset exception " + UTF_8, e);
}
resultRequest.setLabels(convertLabel(label));
}
// processing report with consumerAPI .
LOGGER.debug("Will report result of {}. URL=[{}]. Response=[{}].", resultRequest.getRetStatus().name(),
url, response);
@ -142,6 +161,12 @@ public class EnhancedRestTemplateReporter extends AbstractPolarisReporterAdapter
}
}
private String convertLabel(String label) {
label = label.replaceAll("\"|\\{|\\}", "")
.replaceAll(",", "|");
return label;
}
private void invokeDelegateHandler(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
if (realHasError(response)) {
delegateHandler.handleError(url, method, response);

@ -20,20 +20,26 @@ package com.tencent.cloud.rpc.enhancement.resttemplate;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import com.tencent.cloud.common.constant.PolarisRouterContext;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties;
import com.tencent.polaris.api.core.ConsumerAPI;
import com.tencent.polaris.api.rpc.ServiceCallResult;
import org.assertj.core.api.Assertions;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
@ -46,6 +52,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.client.AbstractClientHttpResponse;
import org.springframework.web.client.ResponseErrorHandler;
import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
@ -70,6 +77,8 @@ public class EnhancedRestTemplateReporterTest {
private ResponseErrorHandler delegate;
@InjectMocks
private EnhancedRestTemplateReporter enhancedRestTemplateReporter;
@Captor
private ArgumentCaptor captor;
@BeforeClass
public static void beforeClass() {
@ -119,9 +128,13 @@ public class EnhancedRestTemplateReporterTest {
enhancedRestTemplateReporter.hasError(response);
URI uri = mock(URI.class);
String labels = URLEncoder.encode("{\"k1\":\"v1\",\"k2\":\"v2\"}", UTF_8);
response.getHeaders().set(PolarisRouterContext.ROUTER_LABELS, labels);
enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, response);
verify(consumerAPI, times(2)).updateServiceCallResult(any());
verify(consumerAPI, times(2)).updateServiceCallResult((ServiceCallResult) captor.capture());
ServiceCallResult value = (ServiceCallResult) captor.getValue();
Assertions.assertThat(value.getLabels()).isEqualTo("k1:v1|k2:v2");
verify(delegate).handleError(uri, HttpMethod.GET, response);
}

Loading…
Cancel
Save