diff --git a/CHANGELOG.md b/CHANGELOG.md index 566d66e95..ebb13d685 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,3 +5,4 @@ - [feat: Enhance default configuration to support `application*.yaml` and `bootstrap*.yaml`.](https://github.com/Tencent/spring-cloud-tencent/pull/985) - [feat:Remove error log from `DecodeTransferMetadataReactiveFilter`.](https://github.com/Tencent/spring-cloud-tencent/pull/989) - [Feature: add AssemblyFlow to support tsf.](https://github.com/Tencent/spring-cloud-tencent/pull/993) +- [Refactoring: Refactor Circuitbreaker ut.](https://github.com/Tencent/spring-cloud-tencent/pull/997) diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java index 89ab8154e..cbe789b76 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerMockServerTest.java @@ -77,13 +77,9 @@ public class PolarisCircuitBreakerMockServerTest { mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties("spring.cloud.polaris.service")) .thenReturn(SERVICE_CIRCUIT_BREAKER); - try { - namingServer = NamingServer.startNamingServer(-1); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { + namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_CIRCUIT_BREAKER); CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); @@ -100,6 +96,7 @@ public class PolarisCircuitBreakerMockServerTest { if (null != namingServer) { namingServer.terminate(); } + mockedApplicationContextAwareUtils.close(); } @Test diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java similarity index 90% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerAutoConfigurationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java index 24801dbea..a35694c2b 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerAutoConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfigurationTest.java @@ -15,12 +15,9 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.config; import com.tencent.cloud.polaris.circuitbreaker.common.CircuitBreakerConfigModifier; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.config.ReactivePolarisCircuitBreakerAutoConfiguration; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration; import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfigurationTest.java similarity index 82% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfigurationTest.java index c78784308..653ba8ffe 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerBootstrapConfigurationTest.java @@ -15,12 +15,8 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.config; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerBootstrapConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.config.ReactivePolarisCircuitBreakerAutoConfiguration; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration; import org.junit.jupiter.api.Test; diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFeignIntegrationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFeignIntegrationTest.java similarity index 85% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFeignIntegrationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFeignIntegrationTest.java index 8712d4f77..085a8e9fe 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerFeignIntegrationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFeignIntegrationTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.feign; import java.io.BufferedReader; @@ -26,7 +26,6 @@ import java.lang.reflect.InvocationTargetException; import java.nio.charset.StandardCharsets; import java.util.stream.Collectors; -import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration; import com.tencent.polaris.api.pojo.ServiceKey; @@ -36,10 +35,10 @@ import com.tencent.polaris.client.util.Utils; import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto; import com.tencent.polaris.test.common.TestUtils; import com.tencent.polaris.test.mock.discovery.NamingServer; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -50,11 +49,12 @@ import org.springframework.cloud.openfeign.FallbackFactory; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; +import org.springframework.context.annotation.Primary; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -69,10 +69,9 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen properties = { "spring.cloud.gateway.enabled=false", "feign.circuitbreaker.enabled=true", - "spring.cloud.polaris.namespace=default", - "spring.cloud.polaris.service=Test" + "spring.cloud.polaris.namespace=" + NAMESPACE_TEST, + "spring.cloud.polaris.service=test" }) -@DirtiesContext public class PolarisCircuitBreakerFeignIntegrationTest { private static final String TEST_SERVICE_NAME = "test-service-callee"; @@ -89,15 +88,6 @@ public class PolarisCircuitBreakerFeignIntegrationTest { @Autowired private BazService bazService; - private static NamingServer namingServer; - - @AfterAll - public static void afterAll() { - if (null != namingServer) { - namingServer.terminate(); - } - } - @Test public void contextLoads() throws Exception { assertThat(echoService).isNotNull(); @@ -140,23 +130,28 @@ public class PolarisCircuitBreakerFeignIntegrationTest { } @Bean - public CircuitBreakAPI circuitBreakAPI() throws InvalidProtocolBufferException { - try { - namingServer = NamingServer.startNamingServer(10081); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { + public PreDestroy preDestroy(NamingServer namingServer) { + return new PreDestroy(namingServer); + } - } - ServiceKey serviceKey = new ServiceKey("default", TEST_SERVICE_NAME); + @Bean + public NamingServer namingServer() throws IOException { + NamingServer namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); + ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME); CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); - InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader().getResourceAsStream("circuitBreakerRule.json"); + InputStream inputStream = PolarisCircuitBreakerFeignIntegrationTest.class.getClassLoader().getResourceAsStream("circuitBreakerRule.json"); String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("")); JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder); CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build(); CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder().addRules(circuitBreakerRule).build(); namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker); + return namingServer; + } + + @Bean + public CircuitBreakAPI circuitBreakAPI(NamingServer namingServer) { com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress(); return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration); } @@ -164,6 +159,7 @@ public class PolarisCircuitBreakerFeignIntegrationTest { } @FeignClient(value = TEST_SERVICE_NAME, contextId = "1", fallback = EchoServiceFallback.class) + @Primary public interface EchoService { @RequestMapping(path = "echo/{str}") @@ -232,4 +228,16 @@ public class PolarisCircuitBreakerFeignIntegrationTest { } + public static class PreDestroy implements DisposableBean { + + private final NamingServer namingServer; + public PreDestroy(NamingServer namingServer) { + this.namingServer = namingServer; + } + @Override + public void destroy() throws Exception { + namingServer.terminate(); + } + } + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerTargeterTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerTargeterTest.java new file mode 100644 index 000000000..e4d83efa3 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerTargeterTest.java @@ -0,0 +1,89 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.polaris.circuitbreaker.feign; + +import feign.Feign; +import feign.RequestLine; +import feign.Target; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; +import org.springframework.cloud.openfeign.CircuitBreakerNameResolver; +import org.springframework.cloud.openfeign.FeignClientFactoryBean; +import org.springframework.cloud.openfeign.FeignContext; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +/** + * PolarisFeignCircuitBreakerTargeterTest. + * + * @author sean yu + */ +@ExtendWith(MockitoExtension.class) +public class PolarisFeignCircuitBreakerTargeterTest { + + @Mock + CircuitBreakerFactory circuitBreakerFactory; + + @Mock + CircuitBreakerNameResolver circuitBreakerNameResolver; + + @Test + public void testTarget() { + PolarisFeignCircuitBreakerTargeter targeter = new PolarisFeignCircuitBreakerTargeter(circuitBreakerFactory, circuitBreakerNameResolver); + targeter.target(new FeignClientFactoryBean(), new Feign.Builder(), new FeignContext(), new Target.HardCodedTarget<>(TestApi.class, "/test")); + } + + @Test + public void testTarget2() { + PolarisFeignCircuitBreakerTargeter targeter = new PolarisFeignCircuitBreakerTargeter(circuitBreakerFactory, circuitBreakerNameResolver); + FeignClientFactoryBean feignClientFactoryBean = mock(FeignClientFactoryBean.class); + doReturn(TestApi.class).when(feignClientFactoryBean).getFallback(); + doReturn("test").when(feignClientFactoryBean).getName(); + FeignContext feignClientFactory = mock(FeignContext.class); + doReturn(null).when(feignClientFactory).getInstance("test", TestApi.class); + assertThatThrownBy(() -> { + targeter.target(feignClientFactoryBean, new PolarisFeignCircuitBreaker.Builder(), feignClientFactory, new Target.HardCodedTarget<>(TestApi.class, "/test")); + }).isInstanceOf(IllegalStateException.class); + } + + @Test + public void testTarget3() { + PolarisFeignCircuitBreakerTargeter targeter = new PolarisFeignCircuitBreakerTargeter(circuitBreakerFactory, circuitBreakerNameResolver); + FeignClientFactoryBean feignClientFactoryBean = mock(FeignClientFactoryBean.class); + doReturn(void.class).when(feignClientFactoryBean).getFallback(); + doReturn(TestApi.class).when(feignClientFactoryBean).getFallbackFactory(); + doReturn("test").when(feignClientFactoryBean).getName(); + FeignContext feignClientFactory = mock(FeignContext.class); + doReturn(Object.class).when(feignClientFactory).getInstance("test", TestApi.class); + assertThatThrownBy(() -> { + targeter.target(feignClientFactoryBean, new PolarisFeignCircuitBreaker.Builder(), feignClientFactory, new Target.HardCodedTarget<>(TestApi.class, "/test")); + }).isInstanceOf(IllegalStateException.class); + } + + interface TestApi { + @RequestLine("GET /test") + void test(); + } + +} diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerGatewayIntegrationTest.java similarity index 85% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerGatewayIntegrationTest.java index 45c8d20fd..ab07a1a3b 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerGatewayIntegrationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/gateway/PolarisCircuitBreakerGatewayIntegrationTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.gateway; import java.io.BufferedReader; @@ -28,9 +28,7 @@ import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; -import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; -import com.tencent.cloud.polaris.circuitbreaker.gateway.PolarisCircuitBreakerFilterFactory; import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory; @@ -38,11 +36,11 @@ import com.tencent.polaris.client.util.Utils; import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto; import com.tencent.polaris.test.common.TestUtils; import com.tencent.polaris.test.mock.discovery.NamingServer; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import reactor.core.publisher.Mono; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; @@ -60,6 +58,7 @@ import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV; import static org.assertj.core.api.Assertions.assertThat; @@ -72,8 +71,8 @@ import static org.assertj.core.api.Assertions.assertThat; webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { "spring.cloud.gateway.enabled=true", - "spring.cloud.polaris.namespace=default", - "spring.cloud.polaris.service=Test", + "spring.cloud.polaris.namespace=" + NAMESPACE_TEST, + "spring.cloud.polaris.service=test", "spring.main.web-application-type=reactive", "httpbin=http://localhost:${wiremock.server.port}" }, @@ -92,15 +91,6 @@ public class PolarisCircuitBreakerGatewayIntegrationTest { @Autowired private ApplicationContext applicationContext; - private static NamingServer namingServer; - - @AfterAll - public static void afterAll() { - if (null != namingServer) { - namingServer.terminate(); - } - } - @Test public void fallback() throws Exception { SpringCloudCircuitBreakerFilterFactory.Config config = new SpringCloudCircuitBreakerFilterFactory.Config(); @@ -163,23 +153,28 @@ public class PolarisCircuitBreakerGatewayIntegrationTest { public static class TestApplication { @Bean - public CircuitBreakAPI circuitBreakAPI() throws InvalidProtocolBufferException { - try { - namingServer = NamingServer.startNamingServer(10081); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { + public PreDestroy preDestroy(NamingServer namingServer) { + return new PreDestroy(namingServer); + } - } - ServiceKey serviceKey = new ServiceKey("default", TEST_SERVICE_NAME); + @Bean + public NamingServer namingServer() throws IOException { + NamingServer namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); + ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME); CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); - InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader().getResourceAsStream("circuitBreakerRule.json"); + InputStream inputStream = PolarisCircuitBreakerGatewayIntegrationTest.class.getClassLoader().getResourceAsStream("circuitBreakerRule.json"); String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("")); JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder); CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build(); CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder().addRules(circuitBreakerRule).build(); namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker); + return namingServer; + } + + @Bean + public CircuitBreakAPI circuitBreakAPI(NamingServer namingServer) throws IOException { com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress(); return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration); } @@ -227,4 +222,16 @@ public class PolarisCircuitBreakerGatewayIntegrationTest { } + public static class PreDestroy implements DisposableBean { + + private final NamingServer namingServer; + public PreDestroy(NamingServer namingServer) { + this.namingServer = namingServer; + } + @Override + public void destroy() throws Exception { + namingServer.terminate(); + } + } + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateIntegrationTest.java similarity index 85% rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java rename to spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateIntegrationTest.java index 3e12daec8..75d931f2e 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerIntegrationTest.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerRestTemplateIntegrationTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.circuitbreaker; +package com.tencent.cloud.polaris.circuitbreaker.resttemplate; import java.io.BufferedReader; import java.io.IOException; @@ -27,12 +27,8 @@ import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.stream.Collectors; -import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.util.JsonFormat; import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerFeignClientAutoConfiguration; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerFallback; -import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreakerHttpResponse; import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory; @@ -40,10 +36,10 @@ import com.tencent.polaris.client.util.Utils; import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto; import com.tencent.polaris.test.common.TestUtils; import com.tencent.polaris.test.mock.discovery.NamingServer; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -57,7 +53,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.client.ExpectedCount; import org.springframework.test.web.client.MockRestServiceServer; @@ -67,6 +62,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.DefaultUriBuilderFactory; +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV; import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; @@ -79,27 +75,17 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat */ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = RANDOM_PORT, - classes = PolarisCircuitBreakerIntegrationTest.TestConfig.class, + classes = PolarisCircuitBreakerRestTemplateIntegrationTest.TestConfig.class, properties = { "spring.cloud.gateway.enabled=false", "feign.circuitbreaker.enabled=true", - "spring.cloud.polaris.namespace=default", + "spring.cloud.polaris.namespace=" + NAMESPACE_TEST, "spring.cloud.polaris.service=test" }) -@DirtiesContext -public class PolarisCircuitBreakerIntegrationTest { +public class PolarisCircuitBreakerRestTemplateIntegrationTest { private static final String TEST_SERVICE_NAME = "test-service-callee"; - private static NamingServer namingServer; - - @AfterAll - public static void afterAll() { - if (null != namingServer) { - namingServer.terminate(); - } - } - @Autowired @Qualifier("defaultRestTemplate") private RestTemplate defaultRestTemplate; @@ -168,14 +154,14 @@ public class PolarisCircuitBreakerIntegrationTest { public static class TestConfig { @Bean - @PolarisCircuitBreaker(fallback = "fallback") + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker(fallback = "fallback") public RestTemplate defaultRestTemplate() { return new RestTemplate(); } @Bean @LoadBalanced - @PolarisCircuitBreaker + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker public RestTemplate restTemplateFallbackFromPolaris() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -185,7 +171,7 @@ public class PolarisCircuitBreakerIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback.class) + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback.class) public RestTemplate restTemplateFallbackFromCode() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -195,7 +181,7 @@ public class PolarisCircuitBreakerIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback2.class) + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback2.class) public RestTemplate restTemplateFallbackFromCode2() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -205,7 +191,7 @@ public class PolarisCircuitBreakerIntegrationTest { @Bean @LoadBalanced - @PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback3.class) + @com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker(fallbackClass = CustomPolarisCircuitBreakerFallback3.class) public RestTemplate restTemplateFallbackFromCode3() { DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://" + TEST_SERVICE_NAME); RestTemplate restTemplate = new RestTemplate(); @@ -239,23 +225,27 @@ public class PolarisCircuitBreakerIntegrationTest { } @Bean - public CircuitBreakAPI circuitBreakAPI() throws InvalidProtocolBufferException { - try { - namingServer = NamingServer.startNamingServer(10081); - System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); - } - catch (IOException e) { - - } - ServiceKey serviceKey = new ServiceKey("default", TEST_SERVICE_NAME); - + public NamingServer namingServer() throws IOException { + NamingServer namingServer = NamingServer.startNamingServer(-1); + System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort())); + ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, TEST_SERVICE_NAME); CircuitBreakerProto.CircuitBreakerRule.Builder circuitBreakerRuleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder(); - InputStream inputStream = PolarisCircuitBreakerMockServerTest.class.getClassLoader().getResourceAsStream("circuitBreakerRule.json"); + InputStream inputStream = PolarisCircuitBreakerRestTemplateIntegrationTest.class.getClassLoader().getResourceAsStream("circuitBreakerRule.json"); String json = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("")); JsonFormat.parser().ignoringUnknownFields().merge(json, circuitBreakerRuleBuilder); CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule = circuitBreakerRuleBuilder.build(); CircuitBreakerProto.CircuitBreaker circuitBreaker = CircuitBreakerProto.CircuitBreaker.newBuilder().addRules(circuitBreakerRule).build(); namingServer.getNamingService().setCircuitBreaker(serviceKey, circuitBreaker); + return namingServer; + } + + @Bean + public PreDestroy preDestroy(NamingServer namingServer) { + return new PreDestroy(namingServer); + } + + @Bean + public CircuitBreakAPI circuitBreakAPI(NamingServer namingServer) { com.tencent.polaris.api.config.Configuration configuration = TestUtils.configWithEnvAddress(); return CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configuration); } @@ -309,5 +299,17 @@ public class PolarisCircuitBreakerIntegrationTest { } } + public static class PreDestroy implements DisposableBean { + + private final NamingServer namingServer; + public PreDestroy(NamingServer namingServer) { + this.namingServer = namingServer; + } + @Override + public void destroy() throws Exception { + namingServer.terminate(); + } + } + } diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java index e6213dbab..d05a0dcc2 100644 --- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java +++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/util/PolarisCircuitBreakerUtilsTests.java @@ -35,6 +35,7 @@ import org.mockito.Mockito; import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyString; public class PolarisCircuitBreakerUtilsTests { @@ -68,4 +69,11 @@ public class PolarisCircuitBreakerUtilsTests { PolarisCircuitBreakerUtils.reportStatus(consumerAPI, conf, new CallAbortedException("mock", new CircuitBreakerStatus.FallbackInfo(0, new HashMap<>(), ""))); } + @Test + public void testResolveCircuitBreakerId() { + assertThat(PolarisCircuitBreakerUtils.resolveCircuitBreakerId("test_svc")).isEqualTo(new String[]{NAMESPACE_TEST, "test_svc", ""}); + assertThat(PolarisCircuitBreakerUtils.resolveCircuitBreakerId("test_svc#test_path")).isEqualTo(new String[]{NAMESPACE_TEST, "test_svc", "test_path"}); + assertThat(PolarisCircuitBreakerUtils.resolveCircuitBreakerId("test_ns#test_svc#test_path")).isEqualTo(new String[]{"test_ns", "test_svc", "test_path"}); + } + } diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java index dfa4148b1..95807dbab 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java @@ -28,20 +28,23 @@ import org.springframework.core.Ordered; public class PluginOrderConstant { public static class ClientPluginOrder { + /** * order for - * {@link com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter} + * {@link com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter} * and - * {@link com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter}. + * {@link com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter}. */ public static final int CONSUMER_REPORTER_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 1; + /** * order for - * {@link com.tencent.cloud.rpc.enhancement.plugin.reporter.SuccessPolarisReporter} + * {@link com.tencent.cloud.polaris.circuitbreaker.reporter.SuccessCircuitBreakerReporter} * and - * {@link com.tencent.cloud.rpc.enhancement.plugin.reporter.ExceptionPolarisReporter}. + * {@link com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter}. */ public static final int CIRCUIT_BREAKER_REPORTER_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 2; + /** * order for * {@link com.tencent.cloud.rpc.enhancement.plugin.assembly.client.AssemblyClientPreHook}