diff --git a/CHANGELOG.md b/CHANGELOG.md index cecc1b1a2..963543902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,3 +9,4 @@ - [feature: improve circuit breaker usage.](https://github.com/Tencent/spring-cloud-tencent/pull/913) - [fix:fix nacos and consul registration.](https://github.com/Tencent/spring-cloud-tencent/pull/921) - [Documentation content changes: add circuitbreaker readme.](https://github.com/Tencent/spring-cloud-tencent/pull/930) +- [fix: fix PolarisRouterServiceInstanceListSupplier npe with reactive feign.](https://github.com/Tencent/spring-cloud-tencent/pull/926) \ No newline at end of file diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplier.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplier.java index dddc69652..4f9bd9f94 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplier.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplier.java @@ -97,12 +97,14 @@ public class PolarisRouterServiceInstanceListSupplier extends DelegatingServiceI PolarisRouterContext routerContext = null; DefaultRequestContext requestContext = (DefaultRequestContext) request.getContext(); - if (requestContext instanceof RequestDataContext) { - routerContext = buildRouterContext(((RequestDataContext) requestContext).getClientRequest().getHeaders()); - } - else if (requestContext.getClientRequest() instanceof PolarisLoadBalancerRequest) { - routerContext = buildRouterContext(((PolarisLoadBalancerRequest) requestContext.getClientRequest()).getRequest() - .getHeaders()); + if (requestContext != null) { + if (requestContext instanceof RequestDataContext) { + routerContext = buildRouterContext(((RequestDataContext) requestContext).getClientRequest().getHeaders()); + } + else if (requestContext.getClientRequest() instanceof PolarisLoadBalancerRequest) { + routerContext = buildRouterContext(((PolarisLoadBalancerRequest) requestContext.getClientRequest()).getRequest() + .getHeaders()); + } } if (routerContext == null) { diff --git a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplierTest.java b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplierTest.java index 00a30183a..84d2a738c 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplierTest.java +++ b/spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/PolarisRouterServiceInstanceListSupplierTest.java @@ -38,7 +38,9 @@ import com.tencent.cloud.polaris.router.config.properties.PolarisRuleBasedRouter import com.tencent.cloud.polaris.router.interceptor.MetadataRouterRequestInterceptor; import com.tencent.cloud.polaris.router.interceptor.NearbyRouterRequestInterceptor; import com.tencent.cloud.polaris.router.interceptor.RuleBasedRouterRequestInterceptor; +import com.tencent.cloud.polaris.router.resttemplate.PolarisLoadBalancerRequest; import com.tencent.cloud.polaris.router.spi.RouterRequestInterceptor; +import com.tencent.cloud.polaris.router.spi.RouterResponseInterceptor; import com.tencent.polaris.api.exception.PolarisException; import com.tencent.polaris.api.pojo.DefaultInstance; import com.tencent.polaris.api.pojo.DefaultServiceInstances; @@ -63,6 +65,7 @@ import reactor.core.publisher.Flux; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.DefaultRequest; +import org.springframework.cloud.client.loadbalancer.DefaultRequestContext; import org.springframework.cloud.client.loadbalancer.RequestData; import org.springframework.cloud.client.loadbalancer.RequestDataContext; import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; @@ -219,7 +222,7 @@ public class PolarisRouterServiceInstanceListSupplierTest { setTransitiveMetadata(); PolarisRouterServiceInstanceListSupplier polarisSupplier = new PolarisRouterServiceInstanceListSupplier( - delegate, routerAPI, requestInterceptors, null); + delegate, routerAPI, requestInterceptors, Collections.singletonList(new TestRouterResponseInterceptor())); ProcessRoutersResponse assembleResponse = assembleProcessRoutersResponse(); when(routerAPI.processRouters(any())).thenReturn(assembleResponse); @@ -279,6 +282,30 @@ public class PolarisRouterServiceInstanceListSupplierTest { } } + @Test + public void testGet03() { + try (MockedStatic mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class)) { + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn(testCallerService); + MetadataContextHolder.set(new MetadataContext()); + mockedApplicationContextAwareUtils.when(() -> delegate.get()) + .thenReturn(assembleServers()); + mockedApplicationContextAwareUtils.when(() -> routerAPI.processRouters(any())) + .thenReturn(new ProcessRoutersResponse(new DefaultServiceInstances(null, new ArrayList<>()))); + + PolarisRouterServiceInstanceListSupplier polarisSupplier = new PolarisRouterServiceInstanceListSupplier( + delegate, routerAPI, requestInterceptors, null); + + MockServerHttpRequest httpRequest = MockServerHttpRequest.get("/" + testCalleeService + "/users") + .header("k1", "v1") + .header(RouterConstant.ROUTER_LABEL_HEADER, "{\"k1\":\"v1\"}") + .queryParam("userid", "zhangsan") + .build(); + DefaultRequestContext requestDataContext = new DefaultRequestContext(new PolarisLoadBalancerRequest(httpRequest, null), "blue"); + DefaultRequest request = new DefaultRequest(requestDataContext); + assertThat(polarisSupplier.get(request).blockFirst().size()).isEqualTo(0); + } + } private void setTransitiveMetadata() { if (initTransitiveMetadata.compareAndSet(false, true)) { // mock transitive metadata @@ -325,4 +352,11 @@ public class PolarisRouterServiceInstanceListSupplierTest { } return Flux.fromIterable(Collections.singletonList(servers)); } + + public class TestRouterResponseInterceptor implements RouterResponseInterceptor { + @Override + public void apply(ProcessRoutersResponse response, PolarisRouterContext routerContext) { + // do nothing + } + } }