feat:support smooth upgrade from tsf. (#1542)
Co-authored-by: Haotian Zhang <skyebefreeman@qq.com>pull/1543/head
parent
853202b1f9
commit
7e6c55e35f
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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 org.springframework.tsf.auth.annotation;
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty annotation. Compatible with old versions TSF SDK.
|
||||||
|
* <p>
|
||||||
|
* Deprecated since 2.0.0.0.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
public @interface EnableTsfAuth {
|
||||||
|
|
||||||
|
}
|
@ -1,2 +1,5 @@
|
|||||||
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||||
|
com.tencent.cloud.polaris.auth.config.PolarisAuthPropertiesAutoConfiguration,\
|
||||||
|
com.tencent.cloud.polaris.auth.config.PolarisAuthAutoConfiguration
|
||||||
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||||
com.tencent.cloud.polaris.auth.config.PolarisAuthPropertiesBootstrapConfiguration
|
com.tencent.cloud.polaris.auth.config.PolarisAuthPropertiesBootstrapConfiguration
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
com.tencent.cloud.polaris.auth.config.PolarisAuthPropertiesAutoConfiguration
|
|
||||||
com.tencent.cloud.polaris.auth.config.PolarisAuthAutoConfiguration
|
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.auth.config;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {@link PolarisAuthProperties}.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
public class PolarisAuthPropertiesTest {
|
||||||
|
|
||||||
|
private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
||||||
|
.withConfiguration(AutoConfigurations.of(PolarisAuthPropertiesAutoConfiguration.class))
|
||||||
|
.withPropertyValues("spring.cloud.polaris.auth.enabled=false");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAndSet() {
|
||||||
|
this.applicationContextRunner.run(context -> {
|
||||||
|
PolarisAuthProperties properties = context.getBean(PolarisAuthProperties.class);
|
||||||
|
assertThat(properties.isEnabled()).isFalse();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFallbackFactory.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/feign/PolarisCircuitBreakerFallbackFactory.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerFallbackFactory.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/feign/PolarisCircuitBreakerFallbackFactory.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolver.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/feign/PolarisCircuitBreakerNameResolver.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolver.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/feign/PolarisCircuitBreakerNameResolver.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreaker.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/feign/PolarisFeignCircuitBreaker.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreaker.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/feign/PolarisFeignCircuitBreaker.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerInvocationHandler.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/feign/PolarisFeignCircuitBreakerInvocationHandler.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerInvocationHandler.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/feign/PolarisFeignCircuitBreakerInvocationHandler.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerFluxOperator.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/reactor/PolarisCircuitBreakerFluxOperator.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerFluxOperator.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/reactor/PolarisCircuitBreakerFluxOperator.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerMonoOperator.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/reactor/PolarisCircuitBreakerMonoOperator.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerMonoOperator.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/reactor/PolarisCircuitBreakerMonoOperator.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerReactorSubscriber.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/reactor/PolarisCircuitBreakerReactorSubscriber.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerReactorSubscriber.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/reactor/PolarisCircuitBreakerReactorSubscriber.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerReactorTransformer.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/reactor/PolarisCircuitBreakerReactorTransformer.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/reactor/PolarisCircuitBreakerReactorTransformer.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/reactor/PolarisCircuitBreakerReactorTransformer.java
5
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreaker.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisCircuitBreaker.java
5
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreaker.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisCircuitBreaker.java
5
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerFallback.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisCircuitBreakerFallback.java
5
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerFallback.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisCircuitBreakerFallback.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerHttpResponse.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisCircuitBreakerHttpResponse.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/resttemplate/PolarisCircuitBreakerHttpResponse.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisCircuitBreakerHttpResponse.java
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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 org.springframework.cloud.tsf.circuitbreaker.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty annotation. Compatible with old versions TSF SDK.
|
||||||
|
* <p>
|
||||||
|
* Deprecated since 2.0.0.0.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
public @interface EnableTsfCircuitBreaker {
|
||||||
|
}
|
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.common;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import org.springframework.web.reactive.function.client.WebClientResponseException;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for ${@link PolarisResultToErrorCode}.
|
||||||
|
*
|
||||||
|
* @author Shedfree Wu
|
||||||
|
*/
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class PolarisResultToErrorCodeTest {
|
||||||
|
|
||||||
|
private final PolarisResultToErrorCode converter = new PolarisResultToErrorCode();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOnSuccess() {
|
||||||
|
assertThat(converter.onSuccess("any value")).isEqualTo(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOnErrorWithWebClientResponseException() {
|
||||||
|
// Given
|
||||||
|
WebClientResponseException exception = WebClientResponseException.create(
|
||||||
|
404, "Not Found", null, null, null);
|
||||||
|
|
||||||
|
// When
|
||||||
|
int errorCode = converter.onError(exception);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
assertThat(errorCode).isEqualTo(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOnErrorWithCircuitBreakerStatusCodeException() {
|
||||||
|
// When
|
||||||
|
int errorCode = converter.onError(new RuntimeException("test"));
|
||||||
|
|
||||||
|
// Then
|
||||||
|
assertThat(errorCode).isEqualTo(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOnErrorWithUnknownException() {
|
||||||
|
// Given
|
||||||
|
RuntimeException exception = new RuntimeException("Unknown error");
|
||||||
|
|
||||||
|
// When
|
||||||
|
int errorCode = converter.onError(exception);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
assertThat(errorCode).isEqualTo(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCheckClassExist() throws Exception {
|
||||||
|
// Given
|
||||||
|
Method checkClassExist = PolarisResultToErrorCode.class.getDeclaredMethod("checkClassExist", String.class);
|
||||||
|
checkClassExist.setAccessible(true);
|
||||||
|
|
||||||
|
PolarisResultToErrorCode converter = new PolarisResultToErrorCode();
|
||||||
|
|
||||||
|
// test exist class
|
||||||
|
boolean result1 = (boolean) checkClassExist.invoke(converter, "java.lang.String");
|
||||||
|
assertThat(result1).isTrue();
|
||||||
|
|
||||||
|
// test not exist class
|
||||||
|
boolean result2 = (boolean) checkClassExist.invoke(converter, "com.nonexistent.Class");
|
||||||
|
assertThat(result2).isFalse();
|
||||||
|
}
|
||||||
|
}
|
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolverTest.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/instrument/feign/PolarisCircuitBreakerNameResolverTest.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisCircuitBreakerNameResolverTest.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/instrument/feign/PolarisCircuitBreakerNameResolverTest.java
@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.instrument.feign;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.tencent.cloud.polaris.circuitbreaker.exception.FallbackWrapperException;
|
||||||
|
import com.tencent.polaris.api.pojo.CircuitBreakerStatus;
|
||||||
|
import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
|
||||||
|
import feign.InvocationHandlerFactory;
|
||||||
|
import feign.Target;
|
||||||
|
import feign.codec.Decoder;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
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.openfeign.FallbackFactory;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for ${@link PolarisFeignCircuitBreakerInvocationHandler}.
|
||||||
|
*
|
||||||
|
* @author Shedfree Wu
|
||||||
|
*/
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class PolarisFeignCircuitBreakerInvocationHandlerTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Target<?> target;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private InvocationHandlerFactory.MethodHandler methodHandler;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private FallbackFactory<TestInterface> fallbackFactory;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Decoder decoder;
|
||||||
|
|
||||||
|
private Map<Method, InvocationHandlerFactory.MethodHandler> dispatch;
|
||||||
|
private PolarisFeignCircuitBreakerInvocationHandler handler;
|
||||||
|
|
||||||
|
private Method testMethod;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() throws Exception {
|
||||||
|
dispatch = new HashMap<>();
|
||||||
|
|
||||||
|
testMethod = TestInterface.class.getDeclaredMethod("testMethod");
|
||||||
|
dispatch.put(testMethod, methodHandler);
|
||||||
|
|
||||||
|
handler = new PolarisFeignCircuitBreakerInvocationHandler(
|
||||||
|
target,
|
||||||
|
dispatch,
|
||||||
|
fallbackFactory,
|
||||||
|
decoder
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConstructorWithNullTarget() {
|
||||||
|
assertThatThrownBy(() ->
|
||||||
|
new PolarisFeignCircuitBreakerInvocationHandler(
|
||||||
|
null, dispatch, fallbackFactory, decoder
|
||||||
|
)
|
||||||
|
).isInstanceOf(NullPointerException.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testConstructorWithNullDispatch() {
|
||||||
|
assertThatThrownBy(() ->
|
||||||
|
new PolarisFeignCircuitBreakerInvocationHandler(
|
||||||
|
target, null, fallbackFactory, decoder
|
||||||
|
)).isInstanceOf(NullPointerException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testToFallbackMethod() throws Exception {
|
||||||
|
Method method = TestInterface.class.getMethod("testMethod");
|
||||||
|
Map<Method, InvocationHandlerFactory.MethodHandler> testDispatch = new HashMap<>();
|
||||||
|
testDispatch.put(method, methodHandler);
|
||||||
|
|
||||||
|
Map<Method, Method> result = PolarisFeignCircuitBreakerInvocationHandler.toFallbackMethod(testDispatch);
|
||||||
|
|
||||||
|
assertThat(result).isNotNull();
|
||||||
|
assertThat(result.containsKey(method)).isTrue();
|
||||||
|
assertThat(result.get(method)).isEqualTo(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEqualsMethod() throws Throwable {
|
||||||
|
Method equalsMethod = Object.class.getMethod("equals", Object.class);
|
||||||
|
Object mockProxy = mock(Object.class);
|
||||||
|
|
||||||
|
// Test equals with null
|
||||||
|
assertThat((Boolean) handler.invoke(mockProxy, equalsMethod, new Object[] {null})).isFalse();
|
||||||
|
|
||||||
|
// Test equals with non-proxy object
|
||||||
|
assertThat((Boolean) handler.invoke(mockProxy, equalsMethod, new Object[] {new Object()})).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testToStringMethod() throws Throwable {
|
||||||
|
Method toStringMethod = Object.class.getMethod("toString");
|
||||||
|
Object mockProxy = mock(Object.class);
|
||||||
|
when(target.toString()).thenReturn("TestTarget");
|
||||||
|
|
||||||
|
assertThat(handler.invoke(mockProxy, toStringMethod, null)).isEqualTo("TestTarget");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCustomFallbackFactoryWithFallbackError() throws Throwable {
|
||||||
|
// Arrange
|
||||||
|
handler = new PolarisFeignCircuitBreakerInvocationHandler(target, dispatch, fallbackFactory, decoder);
|
||||||
|
Exception originalException = new RuntimeException("Original error");
|
||||||
|
|
||||||
|
when(methodHandler.invoke(any())).thenThrow(originalException);
|
||||||
|
TestImpl testImpl = new TestImpl();
|
||||||
|
when(fallbackFactory.create(any())).thenReturn(testImpl);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
assertThatThrownBy(() -> handler.invoke(null, testMethod, new Object[] {})).isInstanceOf(FallbackWrapperException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCustomFallbackFactoryWithFallbackError2() throws Throwable {
|
||||||
|
// Arrange
|
||||||
|
handler = new PolarisFeignCircuitBreakerInvocationHandler(target, dispatch, fallbackFactory, decoder);
|
||||||
|
Exception originalException = new RuntimeException("Original error");
|
||||||
|
|
||||||
|
when(methodHandler.invoke(any())).thenThrow(originalException);
|
||||||
|
TestImpl2 testImpl = new TestImpl2();
|
||||||
|
when(fallbackFactory.create(any())).thenReturn(testImpl);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
assertThatThrownBy(() -> handler.invoke(null, testMethod, new Object[] {})).
|
||||||
|
isInstanceOf(RuntimeException.class).hasMessage("test");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDefaultFallbackCreation() throws Throwable {
|
||||||
|
// Arrange
|
||||||
|
handler = new PolarisFeignCircuitBreakerInvocationHandler(target, dispatch, null, decoder);
|
||||||
|
CircuitBreakerStatus.FallbackInfo fallbackInfo = new CircuitBreakerStatus.FallbackInfo(200, new HashMap<>(), "mock body");
|
||||||
|
CallAbortedException originalException = new CallAbortedException("test rule", fallbackInfo);
|
||||||
|
|
||||||
|
Object expected = new Object();
|
||||||
|
when(methodHandler.invoke(any())).thenThrow(originalException);
|
||||||
|
when(decoder.decode(any(), any())).thenReturn(expected);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
Object result = handler.invoke(null, testMethod, new Object[] {});
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
assertThat(result).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEquals() {
|
||||||
|
PolarisFeignCircuitBreakerInvocationHandler testHandler = new PolarisFeignCircuitBreakerInvocationHandler(
|
||||||
|
target,
|
||||||
|
dispatch,
|
||||||
|
fallbackFactory,
|
||||||
|
decoder
|
||||||
|
);
|
||||||
|
|
||||||
|
assertThat(testHandler).isEqualTo(handler);
|
||||||
|
assertThat(testHandler.hashCode()).isEqualTo(handler.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TestInterface {
|
||||||
|
String testMethod() throws InvocationTargetException;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TestImpl implements TestInterface {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String testMethod() throws InvocationTargetException {
|
||||||
|
throw new InvocationTargetException(new RuntimeException("test"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TestImpl2 implements TestInterface {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String testMethod() throws InvocationTargetException {
|
||||||
|
throw new RuntimeException("test");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerTargeterTest.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/instrument/feign/PolarisFeignCircuitBreakerTargeterTest.java
2
spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignCircuitBreakerTargeterTest.java → spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/instrument/feign/PolarisFeignCircuitBreakerTargeterTest.java
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.instrument.feign;
|
||||||
|
|
||||||
|
import feign.Feign;
|
||||||
|
import feign.RequestLine;
|
||||||
|
import feign.Target;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link PolarisFeignCircuitBreaker}.
|
||||||
|
*/
|
||||||
|
public class PolarisFeignCircuitBreakerTest {
|
||||||
|
|
||||||
|
private PolarisFeignCircuitBreaker.Builder builder;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
builder = PolarisFeignCircuitBreaker.builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuilderNotNull() {
|
||||||
|
assertThat(builder).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTargetWithFallback() {
|
||||||
|
// Mock the target
|
||||||
|
Class<MyService> targetType = MyService.class;
|
||||||
|
String name = "myService";
|
||||||
|
Target<MyService> target = mock(Target.class);
|
||||||
|
|
||||||
|
// mock return value
|
||||||
|
when(target.type()).thenReturn(targetType);
|
||||||
|
when(target.name()).thenReturn(name);
|
||||||
|
|
||||||
|
// Mock the fallback
|
||||||
|
MyService fallback = mock(MyService.class);
|
||||||
|
when(fallback.sayHello()).thenReturn("Fallback Hello");
|
||||||
|
|
||||||
|
// Call the target method
|
||||||
|
MyService result = builder.target(target, fallback);
|
||||||
|
|
||||||
|
// Verify that the result is not null and the fallback factory is used
|
||||||
|
assertThat(result).isNotNull();
|
||||||
|
assertThat(result.sayHello()).isEqualTo("Fallback Hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTargetWithFallbackFactory() {
|
||||||
|
// Mock the target and fallback factory
|
||||||
|
Class<MyService> targetType = MyService.class;
|
||||||
|
String name = "myService";
|
||||||
|
Target<MyService> target = mock(Target.class);
|
||||||
|
|
||||||
|
// mock return value
|
||||||
|
when(target.type()).thenReturn(targetType);
|
||||||
|
when(target.name()).thenReturn(name);
|
||||||
|
|
||||||
|
FallbackFactory<MyService> fallbackFactory = mock(FallbackFactory.class);
|
||||||
|
|
||||||
|
// Mock the fallback from the factory
|
||||||
|
MyService fallback = mock(MyService.class);
|
||||||
|
when(fallback.sayHello()).thenReturn("Fallback Hello");
|
||||||
|
when(fallbackFactory.create(any())).thenReturn(fallback);
|
||||||
|
|
||||||
|
// Call the target method
|
||||||
|
MyService result = builder.target(target, fallbackFactory);
|
||||||
|
|
||||||
|
// Verify that the result is not null and the fallback factory is used
|
||||||
|
assertThat(result).isNotNull();
|
||||||
|
assertThat(result.sayHello()).isEqualTo("Fallback Hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTargetWithoutFallback() {
|
||||||
|
// Mock the target
|
||||||
|
Class<MyService> targetType = MyService.class;
|
||||||
|
String name = "myService";
|
||||||
|
Target<MyService> target = mock(Target.class);
|
||||||
|
|
||||||
|
// mock return value
|
||||||
|
when(target.type()).thenReturn(targetType);
|
||||||
|
when(target.name()).thenReturn(name);
|
||||||
|
|
||||||
|
// Call the target method
|
||||||
|
MyService result = builder.target(target);
|
||||||
|
|
||||||
|
// Verify that the result is not null
|
||||||
|
assertThat(result).isNotNull();
|
||||||
|
// Additional verifications can be added here based on the implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuildWithNullableFallbackFactory() {
|
||||||
|
// Call the build method with a null fallback factory
|
||||||
|
Feign feign = builder.build(null);
|
||||||
|
|
||||||
|
// Verify that the Feign instance is not null
|
||||||
|
assertThat(feign).isNotNull();
|
||||||
|
// Additional verifications can be added here based on the implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface MyService {
|
||||||
|
@RequestLine("GET /hello")
|
||||||
|
String sayHello();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.config.adapter;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
|
||||||
|
import com.tencent.cloud.polaris.config.spring.property.SpringValueRegistry;
|
||||||
|
import com.tencent.polaris.configuration.api.core.ConfigFileService;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
|
||||||
|
import org.springframework.cloud.context.refresh.ContextRefresher;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.verifyNoInteractions;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link PolarisRefreshEntireContextRefresher}.
|
||||||
|
*
|
||||||
|
* @author Shedfree Wu
|
||||||
|
*/
|
||||||
|
public class PolarisRefreshEntireContextRefresherTest {
|
||||||
|
@Mock
|
||||||
|
private PolarisConfigProperties polarisConfigProperties;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private SpringValueRegistry springValueRegistry;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ConfigFileService configFileService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ContextRefresher contextRefresher;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ConfigurableApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private PolarisConfigCustomExtensionLayer mockExtensionLayer;
|
||||||
|
|
||||||
|
private PolarisRefreshEntireContextRefresher refresher;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
MockitoAnnotations.openMocks(this);
|
||||||
|
refresher = new PolarisRefreshEntireContextRefresher(
|
||||||
|
polarisConfigProperties,
|
||||||
|
springValueRegistry,
|
||||||
|
configFileService,
|
||||||
|
contextRefresher
|
||||||
|
);
|
||||||
|
refresher.setApplicationContext(applicationContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRefreshSpringValue() {
|
||||||
|
// test refreshSpringValue method, it should do nothing
|
||||||
|
refresher.refreshSpringValue("test.key");
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
verifyNoInteractions(contextRefresher);
|
||||||
|
verifyNoInteractions(springValueRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRefreshConfigurationPropertiesWithRefreshScope() {
|
||||||
|
// Arrange
|
||||||
|
Set<String> changeKeys = new HashSet<>();
|
||||||
|
changeKeys.add("test.key1");
|
||||||
|
changeKeys.add("test.key2");
|
||||||
|
|
||||||
|
// mock test.key1 in refresh scope
|
||||||
|
when(springValueRegistry.isRefreshScopeKey("test.key1")).thenReturn(true);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
refresher.refreshConfigurationProperties(changeKeys);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
verify(contextRefresher, times(1)).refresh();
|
||||||
|
verifyNoInteractions(applicationContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRefreshConfigurationPropertiesWithoutRefreshScope() {
|
||||||
|
// Arrange
|
||||||
|
Set<String> changeKeys = new HashSet<>();
|
||||||
|
changeKeys.add("test.key1");
|
||||||
|
changeKeys.add("test.key2");
|
||||||
|
|
||||||
|
// mock a key not in refresh scope
|
||||||
|
when(springValueRegistry.isRefreshScopeKey(anyString())).thenReturn(false);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
refresher.refreshConfigurationProperties(changeKeys);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
verify(contextRefresher, never()).refresh();
|
||||||
|
verify(applicationContext, times(1))
|
||||||
|
.publishEvent(any(EnvironmentChangeEvent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSetApplicationContext() {
|
||||||
|
// Arrange
|
||||||
|
ConfigurableApplicationContext newContext = mock(ConfigurableApplicationContext.class);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
refresher.setApplicationContext(newContext);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
Set<String> changeKeys = new HashSet<>();
|
||||||
|
changeKeys.add("test.key");
|
||||||
|
when(springValueRegistry.isRefreshScopeKey(anyString())).thenReturn(false);
|
||||||
|
|
||||||
|
refresher.refreshConfigurationProperties(changeKeys);
|
||||||
|
verify(newContext, times(1)).publishEvent(any(EnvironmentChangeEvent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRefreshConfigurationPropertiesWithEmptyChangeKeys() {
|
||||||
|
// Arrange
|
||||||
|
Set<String> changeKeys = new HashSet<>();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
refresher.refreshConfigurationProperties(changeKeys);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
verify(contextRefresher, never()).refresh();
|
||||||
|
verify(applicationContext, times(1))
|
||||||
|
.publishEvent(any(EnvironmentChangeEvent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRefreshConfigurationPropertiesWithMultipleRefreshScopeKeys() {
|
||||||
|
// Arrange
|
||||||
|
Set<String> changeKeys = new HashSet<>();
|
||||||
|
changeKeys.add("test.key1");
|
||||||
|
changeKeys.add("test.key2");
|
||||||
|
changeKeys.add("test.key3");
|
||||||
|
|
||||||
|
// mock multiple keys in refresh scope
|
||||||
|
when(springValueRegistry.isRefreshScopeKey(anyString())).thenReturn(true);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
refresher.refreshConfigurationProperties(changeKeys);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
verify(contextRefresher, times(1)).refresh();
|
||||||
|
verifyNoInteractions(applicationContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPolarisConfigCustomExtensionLayer() throws Exception {
|
||||||
|
refresher.setRegistered(true);
|
||||||
|
|
||||||
|
Field field = PolarisConfigPropertyAutoRefresher.class
|
||||||
|
.getDeclaredField("polarisConfigCustomExtensionLayer");
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(refresher, mockExtensionLayer);
|
||||||
|
|
||||||
|
Method method = PolarisConfigPropertyAutoRefresher.class
|
||||||
|
.getDeclaredMethod("customInitRegisterPolarisConfig", PolarisConfigPropertyAutoRefresher.class);
|
||||||
|
method.setAccessible(true);
|
||||||
|
method.invoke(refresher, refresher);
|
||||||
|
|
||||||
|
|
||||||
|
method = PolarisConfigPropertyAutoRefresher.class.getDeclaredMethod(
|
||||||
|
"customRegisterPolarisConfigPublishChangeListener",
|
||||||
|
PolarisPropertySource.class, PolarisPropertySource.class);
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
method.invoke(refresher, null, null);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
verify(mockExtensionLayer, times(1)).initRegisterConfig(refresher);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.discovery.refresh;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.tencent.polaris.api.pojo.Instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for service instance change.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
public interface ServiceInstanceChangeCallback {
|
||||||
|
|
||||||
|
void callback(List<Instance> currentServiceInstances, List<Instance> addServiceInstances, List<Instance> deleteServiceInstances);
|
||||||
|
}
|
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.discovery.refresh;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
|
||||||
|
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
|
||||||
|
import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClient;
|
||||||
|
import com.tencent.cloud.polaris.discovery.reactive.PolarisReactiveDiscoveryClient;
|
||||||
|
import com.tencent.polaris.api.pojo.Instance;
|
||||||
|
import com.tencent.polaris.api.utils.StringUtils;
|
||||||
|
import com.tencent.polaris.client.util.NamedThreadFactory;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import reactor.util.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call back manager for service instance change.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
public class ServiceInstanceChangeCallbackManager implements ApplicationListener<ApplicationReadyEvent>, BeanPostProcessor {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(ServiceInstanceChangeCallbackManager.class);
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<String, List<ServiceInstanceChangeCallback>> callbackMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private final ScheduledThreadPoolExecutor serviceChangeListenerExecutor;
|
||||||
|
|
||||||
|
public ServiceInstanceChangeCallbackManager() {
|
||||||
|
this.serviceChangeListenerExecutor = new ScheduledThreadPoolExecutor(4, new NamedThreadFactory("service-change-listener"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(String serviceName, List<Instance> oldInstances, List<Instance> newInstances) {
|
||||||
|
|
||||||
|
List<Instance> addInstances = new ArrayList<>();
|
||||||
|
List<Instance> deleteInstances = new ArrayList<>();
|
||||||
|
|
||||||
|
// calculate add instances.
|
||||||
|
for (Instance instance : newInstances) {
|
||||||
|
if (!oldInstances.contains(instance)) {
|
||||||
|
addInstances.add(instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// calculate delete instances.
|
||||||
|
for (Instance instance : oldInstances) {
|
||||||
|
if (!newInstances.contains(instance)) {
|
||||||
|
deleteInstances.add(instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!CollectionUtils.isEmpty(addInstances) || !CollectionUtils.isEmpty(deleteInstances))
|
||||||
|
&& callbackMap.containsKey(serviceName)) {
|
||||||
|
List<ServiceInstanceChangeCallback> callbacks = callbackMap.get(serviceName);
|
||||||
|
|
||||||
|
for (ServiceInstanceChangeCallback callback : callbacks) {
|
||||||
|
serviceChangeListenerExecutor.execute(() -> {
|
||||||
|
try {
|
||||||
|
callback.callback(newInstances, addInstances, deleteInstances);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
LOG.error("exception in callback, service name:{}, ", serviceName, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||||
|
Class<?> clz = bean.getClass();
|
||||||
|
|
||||||
|
if (!ServiceInstanceChangeCallback.class.isAssignableFrom(clz)) {
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
String serviceName = null;
|
||||||
|
if (clz.isAnnotationPresent(ServiceInstanceChangeListener.class)) {
|
||||||
|
ServiceInstanceChangeListener serviceInstanceChangeListener = clz.getAnnotation(ServiceInstanceChangeListener.class);
|
||||||
|
serviceName = serviceInstanceChangeListener.serviceName();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(serviceName)) {
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// process callback
|
||||||
|
if (callbackMap.containsKey(serviceName)) {
|
||||||
|
List<ServiceInstanceChangeCallback> callbacks = callbackMap.get(serviceName);
|
||||||
|
callbacks.add((ServiceInstanceChangeCallback) bean);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
List<ServiceInstanceChangeCallback> callbacks = new ArrayList<>();
|
||||||
|
callbacks.add((ServiceInstanceChangeCallback) bean);
|
||||||
|
callbackMap.put(serviceName, callbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(@NonNull ApplicationReadyEvent event) {
|
||||||
|
PolarisDiscoveryClient polarisDiscoveryClient = ApplicationContextAwareUtils.getBeanIfExists(PolarisDiscoveryClient.class);
|
||||||
|
PolarisReactiveDiscoveryClient polarisReactiveDiscoveryClient = ApplicationContextAwareUtils.getBeanIfExists(PolarisReactiveDiscoveryClient.class);
|
||||||
|
for (String serviceName : callbackMap.keySet()) {
|
||||||
|
try {
|
||||||
|
if (polarisDiscoveryClient != null) {
|
||||||
|
polarisDiscoveryClient.getInstances(serviceName);
|
||||||
|
}
|
||||||
|
else if (polarisReactiveDiscoveryClient != null) {
|
||||||
|
polarisReactiveDiscoveryClient.getInstances(serviceName).subscribe();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG.warn("[{}] no discovery client found.", serviceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Throwable throwable) {
|
||||||
|
LOG.error("Get instances of service [{}] failed.", serviceName, throwable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
spring-cloud-tencent-examples/quickstart-example/quickstart-caller-service/src/main/java/com/tencent/cloud/quickstart/caller/circuitbreaker/CustomFallback.java → spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/ServiceInstanceChangeListener.java
35
spring-cloud-tencent-examples/quickstart-example/quickstart-caller-service/src/main/java/com/tencent/cloud/quickstart/caller/circuitbreaker/CustomFallback.java → spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/discovery/refresh/ServiceInstanceChangeListener.java
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.eager.config;
|
||||||
|
|
||||||
|
import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClient;
|
||||||
|
import com.tencent.cloud.polaris.discovery.reactive.PolarisReactiveDiscoveryClient;
|
||||||
|
import com.tencent.cloud.polaris.eager.instrument.feign.FeignEagerLoadSmartLifecycle;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnProperty(name = "spring.cloud.polaris.discovery.eager-load.enabled", havingValue = "true")
|
||||||
|
public class PolarisEagerLoadAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnClass(name = "feign.Feign")
|
||||||
|
@ConditionalOnProperty(name = "spring.cloud.polaris.discovery.eager-load.feign.enabled", havingValue = "true", matchIfMissing = true)
|
||||||
|
public FeignEagerLoadSmartLifecycle feignEagerLoadSmartLifecycle(
|
||||||
|
ApplicationContext applicationContext, @Autowired(required = false) PolarisDiscoveryClient polarisDiscoveryClient,
|
||||||
|
@Autowired(required = false) PolarisReactiveDiscoveryClient polarisReactiveDiscoveryClient) {
|
||||||
|
return new FeignEagerLoadSmartLifecycle(applicationContext, polarisDiscoveryClient, polarisReactiveDiscoveryClient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.eager.instrument.feign;
|
||||||
|
|
||||||
|
import com.tencent.cloud.common.util.FeignUtil;
|
||||||
|
import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClient;
|
||||||
|
import com.tencent.cloud.polaris.discovery.reactive.PolarisReactiveDiscoveryClient;
|
||||||
|
import com.tencent.polaris.api.utils.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.SmartLifecycle;
|
||||||
|
|
||||||
|
public class FeignEagerLoadSmartLifecycle implements SmartLifecycle {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(FeignEagerLoadSmartLifecycle.class);
|
||||||
|
|
||||||
|
private final ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
private final PolarisDiscoveryClient polarisDiscoveryClient;
|
||||||
|
|
||||||
|
private final PolarisReactiveDiscoveryClient polarisReactiveDiscoveryClient;
|
||||||
|
|
||||||
|
public FeignEagerLoadSmartLifecycle(ApplicationContext applicationContext, PolarisDiscoveryClient polarisDiscoveryClient,
|
||||||
|
PolarisReactiveDiscoveryClient polarisReactiveDiscoveryClient) {
|
||||||
|
this.applicationContext = applicationContext;
|
||||||
|
this.polarisDiscoveryClient = polarisDiscoveryClient;
|
||||||
|
this.polarisReactiveDiscoveryClient = polarisReactiveDiscoveryClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
LOG.info("feign eager-load start");
|
||||||
|
for (String name : applicationContext.getBeanDefinitionNames()) {
|
||||||
|
try {
|
||||||
|
if (name.contains(FeignUtil.FEIGN_CLIENT_SPECIF) && !name.startsWith(FeignUtil.FEIGN_CLIENT_DEFAULT)) {
|
||||||
|
String feignName = FeignUtil.analysisFeignName(name, applicationContext);
|
||||||
|
if (StringUtils.isNotBlank(feignName)) {
|
||||||
|
LOG.info("[{}] eager-load start", feignName);
|
||||||
|
if (polarisDiscoveryClient != null) {
|
||||||
|
polarisDiscoveryClient.getInstances(feignName);
|
||||||
|
}
|
||||||
|
else if (polarisReactiveDiscoveryClient != null) {
|
||||||
|
polarisReactiveDiscoveryClient.getInstances(feignName).subscribe();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG.warn("[{}] no discovery client found.", feignName);
|
||||||
|
}
|
||||||
|
LOG.info("[{}] eager-load end", feignName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG.warn("feign name is blank.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
LOG.error("[{}] eager-load failed.", name, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG.info("feign eager-load end");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRunning() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPhase() {
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.tsf.serviceregistry.watch;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.ecwid.consul.v1.health.model.HealthService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not working anymore. Compatible with old versions TSF SDK.
|
||||||
|
* <p>
|
||||||
|
* Deprecated since 2.0.0.0.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public interface ConsulServiceChangeCallback {
|
||||||
|
|
||||||
|
/** Service change callback function.
|
||||||
|
* @param currentServices Currently available services list
|
||||||
|
* @param addServices Newly added services list
|
||||||
|
* @param deleteServices Removed services list
|
||||||
|
*/
|
||||||
|
void callback(List<HealthService> currentServices, List<HealthService> addServices, List<HealthService> deleteServices);
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.tsf.serviceregistry.watch;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty annotation. Compatible with old versions TSF SDK.
|
||||||
|
* <p>
|
||||||
|
* Deprecated since 2.0.0.0.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Component
|
||||||
|
public @interface LocalServiceChangeListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回调的 currentServices 是否包含当前实例.
|
||||||
|
* @return 是否包含当前实例.
|
||||||
|
*/
|
||||||
|
boolean excludeLocalInstance() default false;
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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 org.springframework.tsf.ratelimit.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty annotation. Compatible with old versions TSF SDK.
|
||||||
|
* <p>
|
||||||
|
* Deprecated since 2.0.0.0.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
public @interface EnableTsfRateLimit {
|
||||||
|
}
|
4
spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisRetryLoadBalancerInterceptor.java → spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/instrument/resttemplate/PolarisRetryLoadBalancerInterceptor.java
4
spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/PolarisRetryLoadBalancerInterceptor.java → spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/instrument/resttemplate/PolarisRetryLoadBalancerInterceptor.java
2
spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/RouterLabelRestTemplateInterceptor.java → spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/instrument/resttemplate/RouterLabelRestTemplateInterceptor.java
2
spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/resttemplate/RouterLabelRestTemplateInterceptor.java → spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/instrument/resttemplate/RouterLabelRestTemplateInterceptor.java
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.tsf.lane.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty annotation. Compatible with old versions TSF SDK.
|
||||||
|
* <p>
|
||||||
|
* Deprecated since 2.0.0.0.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
public @interface EnableTsfLane {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.tsf.femas.adaptor.tsf.governance.zonefilter;
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty annotation. Compatible with old versions TSF SDK.
|
||||||
|
* <p>
|
||||||
|
* Deprecated since 2.0.0.0.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
public @interface EnableTsfZoneFilter {
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.tsf.unit.annotation;
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty annotation. Compatible with old versions TSF SDK.
|
||||||
|
* <p>
|
||||||
|
* Deprecated since 2.0.0.0.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
public @interface EnableTsfUnit {
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.tsf.unit.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty annotation. Compatible with old versions TSF SDK.
|
||||||
|
* <p>
|
||||||
|
* Deprecated since 2.0.0.0.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Inherited
|
||||||
|
@Documented
|
||||||
|
public @interface TsfUnitCall {
|
||||||
|
|
||||||
|
// 单元化下的业务系统名
|
||||||
|
String systemName() default "";
|
||||||
|
|
||||||
|
// 单元化下的是否调用GDU服务
|
||||||
|
boolean global() default false;
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.tsf.unit.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty annotation. Compatible with old versions TSF SDK.
|
||||||
|
* <p>
|
||||||
|
* Deprecated since 2.0.0.0.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Target(ElementType.PARAMETER)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Inherited
|
||||||
|
@Documented
|
||||||
|
public @interface TsfUnitCustomerIdentifier {
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.tsf.unit.annotation;
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty annotation. Compatible with old versions TSF SDK.
|
||||||
|
* <p>
|
||||||
|
* Deprecated since 2.0.0.0.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Inherited
|
||||||
|
@Documented
|
||||||
|
public @interface TsfUnitLocalCall {
|
||||||
|
String className() default "";
|
||||||
|
|
||||||
|
String methodName() default "";
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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 org.springframework.cloud.tsf.route.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty annotation. Compatible with old versions TSF SDK.
|
||||||
|
* <p>
|
||||||
|
* Deprecated since 2.0.0.0.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Inherited
|
||||||
|
public @interface EnableTsfRoute {
|
||||||
|
}
|
||||||
|
|
2
spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/PolarisCachingSpringLoadBalanceFactoryTest.java → spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/feign/PolarisCachingSpringLoadBalanceFactoryTest.java
2
spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/feign/PolarisCachingSpringLoadBalanceFactoryTest.java → spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/feign/PolarisCachingSpringLoadBalanceFactoryTest.java
2
spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java → spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/resttemplate/PolarisLoadBalancerInterceptorTest.java
2
spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/PolarisLoadBalancerInterceptorTest.java → spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/resttemplate/PolarisLoadBalancerInterceptorTest.java
2
spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/RouterLabelRestTemplateInterceptorTest.java → spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/resttemplate/RouterLabelRestTemplateInterceptorTest.java
2
spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/resttemplate/RouterLabelRestTemplateInterceptorTest.java → spring-cloud-starter-tencent-polaris-router/src/test/java/com/tencent/cloud/polaris/router/instrument/resttemplate/RouterLabelRestTemplateInterceptorTest.java
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.common.async;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
|
import com.tencent.cloud.plugin.threadlocal.TaskExecutorWrapper;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
|
import org.springframework.context.annotation.Role;
|
||||||
|
import org.springframework.core.task.TaskExecutor;
|
||||||
|
import org.springframework.scheduling.annotation.AsyncConfigurer;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
|
|
||||||
|
import static com.tencent.cloud.common.metadata.CrossThreadMetadataContext.CROSS_THREAD_METADATA_CONTEXT_CONSUMER;
|
||||||
|
import static com.tencent.cloud.common.metadata.CrossThreadMetadataContext.CROSS_THREAD_METADATA_CONTEXT_SUPPLIER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* polaris async executor for @Async .
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
@ConditionalOnProperty(name = "spring.cloud.tencent.async.enabled")
|
||||||
|
public class PolarisAsyncConfiguration implements AsyncConfigurer {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(PolarisAsyncConfiguration.class);
|
||||||
|
|
||||||
|
@Primary
|
||||||
|
@Bean("polarisAsyncExecutor")
|
||||||
|
public TaskExecutor polarisAsyncExecutor() {
|
||||||
|
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||||
|
int corePoolSize = 10;
|
||||||
|
executor.setCorePoolSize(corePoolSize);
|
||||||
|
int maxPoolSize = 50;
|
||||||
|
executor.setMaxPoolSize(maxPoolSize);
|
||||||
|
int queueCapacity = 10;
|
||||||
|
executor.setQueueCapacity(queueCapacity);
|
||||||
|
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||||
|
String threadNamePrefix = "polaris-async-executor-";
|
||||||
|
executor.setThreadNamePrefix(threadNamePrefix);
|
||||||
|
executor.setWaitForTasksToCompleteOnShutdown(true);
|
||||||
|
executor.setAwaitTerminationSeconds(5);
|
||||||
|
executor.initialize();
|
||||||
|
TaskExecutor executorWrapper = new TaskExecutorWrapper<>(executor, CROSS_THREAD_METADATA_CONTEXT_SUPPLIER, CROSS_THREAD_METADATA_CONTEXT_CONSUMER);
|
||||||
|
logger.info("Created async executor with corePoolSize:{}, maxPoolSize:{}, queueCapacity:{}", corePoolSize, maxPoolSize, queueCapacity);
|
||||||
|
return executorWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Executor getAsyncExecutor() {
|
||||||
|
return polarisAsyncExecutor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
|
||||||
|
return (ex, method, params) -> logger.error("Execute asynchronous tasks '{}' failed.", method, ex);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.common.metadata;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.tencent.cloud.common.util.JacksonUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metadata Context for cross thread.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
public class CrossThreadMetadataContext {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(CrossThreadMetadataContext.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get metadata context from previous thread.
|
||||||
|
*/
|
||||||
|
public static final Supplier<CrossThreadMetadataContext> CROSS_THREAD_METADATA_CONTEXT_SUPPLIER = () -> {
|
||||||
|
CrossThreadMetadataContext crossThreadMetadataContext = new CrossThreadMetadataContext();
|
||||||
|
crossThreadMetadataContext.setMetadataContext(MetadataContextHolder.get());
|
||||||
|
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("Context map is got: {}", JacksonUtils.serialize2Json(crossThreadMetadataContext));
|
||||||
|
}
|
||||||
|
return crossThreadMetadataContext;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set metadata context to current thread.
|
||||||
|
*/
|
||||||
|
public static final Consumer<CrossThreadMetadataContext> CROSS_THREAD_METADATA_CONTEXT_CONSUMER = crossThreadMetadataContext -> {
|
||||||
|
MetadataContextHolder.set(crossThreadMetadataContext.getMetadataContext());
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("Context map is set: {}", JacksonUtils.serialize2Json(crossThreadMetadataContext));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private MetadataContext metadataContext;
|
||||||
|
|
||||||
|
public MetadataContext getMetadataContext() {
|
||||||
|
return metadataContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMetadataContext(MetadataContext metadataContext) {
|
||||||
|
this.metadataContext = metadataContext;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.common.util;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author heihuliliu
|
||||||
|
*/
|
||||||
|
public final class FeignUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feign client spec.
|
||||||
|
*/
|
||||||
|
public static final String FEIGN_CLIENT_SPECIF = ".FeignClientSpecification";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Feign client spec.
|
||||||
|
*/
|
||||||
|
public static final String FEIGN_CLIENT_DEFAULT = "default.";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* regular expression that parses ${xxx} .
|
||||||
|
*/
|
||||||
|
public static final String REGEX = "^[$][{](.*)[}]$";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* replacement of ${xxx}.
|
||||||
|
*/
|
||||||
|
public static final String REPLACEMENT = "$1";
|
||||||
|
|
||||||
|
private FeignUtil() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO If @FeignClient specifies contextId, the service name will not be obtained correctly, but the contextId will be obtained.
|
||||||
|
*
|
||||||
|
* @param name feign name.
|
||||||
|
* @param context application context.
|
||||||
|
* @return service name.
|
||||||
|
*/
|
||||||
|
public static String analysisFeignName(String name, ApplicationContext context) {
|
||||||
|
String feignName = "";
|
||||||
|
String feignPath = name.substring(0, name.indexOf(FEIGN_CLIENT_SPECIF));
|
||||||
|
// Handle the case where the service name is a variable
|
||||||
|
if (feignPath.matches(REGEX)) {
|
||||||
|
feignPath = context.getEnvironment().getProperty(feignPath.replaceAll(REGEX, REPLACEMENT));
|
||||||
|
}
|
||||||
|
if (StringUtils.hasText(feignPath)) {
|
||||||
|
// The case of multi-level paths
|
||||||
|
String[] feignNames = feignPath.split("/");
|
||||||
|
if (feignNames.length > 1) {
|
||||||
|
for (int i = 0; i < feignNames.length; i++) {
|
||||||
|
if (StringUtils.hasText(feignNames[i])) {
|
||||||
|
feignName = feignNames[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
feignName = feignNames[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return feignName;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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.common.util;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.tencent.polaris.threadlocal.cross.CompletableFutureUtils;
|
||||||
|
|
||||||
|
import static com.tencent.cloud.common.metadata.CrossThreadMetadataContext.CROSS_THREAD_METADATA_CONTEXT_CONSUMER;
|
||||||
|
import static com.tencent.cloud.common.metadata.CrossThreadMetadataContext.CROSS_THREAD_METADATA_CONTEXT_SUPPLIER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Polaris CompletableFuture Utils.
|
||||||
|
*
|
||||||
|
* @author Haotian Zhang
|
||||||
|
*/
|
||||||
|
public final class PolarisCompletableFutureUtils {
|
||||||
|
|
||||||
|
private PolarisCompletableFutureUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
|
||||||
|
return CompletableFutureUtils.supplyAsync(supplier, CROSS_THREAD_METADATA_CONTEXT_SUPPLIER, CROSS_THREAD_METADATA_CONTEXT_CONSUMER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CompletableFuture<Void> runAsync(Runnable runnable) {
|
||||||
|
return CompletableFutureUtils.runAsync(runnable, CROSS_THREAD_METADATA_CONTEXT_SUPPLIER, CROSS_THREAD_METADATA_CONTEXT_CONSUMER);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 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 org.springframework.tsf.core.util;
|
||||||
|
|
||||||
|
import com.tencent.cloud.common.util.ApplicationContextAwareUtils;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring context utils.
|
||||||
|
* <p>
|
||||||
|
* Deprecated since 2.0.0.0.
|
||||||
|
*
|
||||||
|
* @author hongweizhu
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public class TsfSpringContextAware {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get application context.
|
||||||
|
* @return application context
|
||||||
|
*/
|
||||||
|
public static ApplicationContext getApplicationContext() {
|
||||||
|
return ApplicationContextAwareUtils.getApplicationContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
// do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get application property.
|
||||||
|
* @param key property name
|
||||||
|
* @return property value
|
||||||
|
*/
|
||||||
|
public static String getProperties(String key) {
|
||||||
|
return ApplicationContextAwareUtils.getProperties(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get application property. If null, return default.
|
||||||
|
* @param key property name
|
||||||
|
* @param defaultValue default value
|
||||||
|
* @return property value
|
||||||
|
*/
|
||||||
|
public static String getProperties(String key, String defaultValue) {
|
||||||
|
return ApplicationContextAwareUtils.getProperties(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T getBean(Class<T> requiredType) {
|
||||||
|
return ApplicationContextAwareUtils.getBean(requiredType);
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue