diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/beanprocessor/LoadBalancerInterceptorBeanPostProcessor.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/beanprocessor/LoadBalancerInterceptorBeanPostProcessor.java
deleted file mode 100644
index 72596b238..000000000
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/beanprocessor/LoadBalancerInterceptorBeanPostProcessor.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Tencent is pleased to support the open source community by making spring-cloud-tencent available.
- *
- * Copyright (C) 2021 Tencent. 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.beanprocessor;
-
-import com.tencent.cloud.polaris.circuitbreaker.instrument.resttemplate.PolarisLoadBalancerInterceptor;
-import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
-
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.config.BeanPostProcessor;
-import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
-import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
-import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestFactory;
-import org.springframework.core.Ordered;
-import org.springframework.lang.NonNull;
-
-/**
- * LoadBalancerInterceptorBeanPostProcessor is used to wrap the default LoadBalancerInterceptor implementation and returns a custom PolarisLoadBalancerInterceptor.
- *
- * @author Shedfree Wu
- */
-public class LoadBalancerInterceptorBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware, Ordered {
- /**
- * The order of the bean post processor. if user want to wrap it(CustomLoadBalancerInterceptor -> PolarisLoadBalancerInterceptor), CustomLoadBalancerInterceptorBeanPostProcessor's order should be bigger than ${@link POLARIS_LOAD_BALANCER_INTERCEPTOR_POST_PROCESSOR_ORDER}.
- */
- public static final int POLARIS_LOAD_BALANCER_INTERCEPTOR_POST_PROCESSOR_ORDER = 0;
-
- private BeanFactory factory;
-
- @Override
- public void setBeanFactory(@NonNull BeanFactory beanFactory) throws BeansException {
- this.factory = beanFactory;
- }
-
- @Override
- public Object postProcessBeforeInitialization(@NonNull Object bean, @NonNull String beanName) throws BeansException {
- if (bean instanceof LoadBalancerInterceptor) {
- // Support rest template router.
- // Replaces the default LoadBalancerInterceptor implementation and returns a custom PolarisLoadBalancerInterceptor
- LoadBalancerRequestFactory requestFactory = this.factory.getBean(LoadBalancerRequestFactory.class);
- LoadBalancerClient loadBalancerClient = this.factory.getBean(LoadBalancerClient.class);
- EnhancedPluginRunner pluginRunner = this.factory.getBean(EnhancedPluginRunner.class);
- return new PolarisLoadBalancerInterceptor(loadBalancerClient, requestFactory, pluginRunner);
- }
- return bean;
- }
-
- @Override
- public int getOrder() {
- return POLARIS_LOAD_BALANCER_INTERCEPTOR_POST_PROCESSOR_ORDER;
- }
-}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java
index 0f01fa1bf..e7d85492d 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/config/PolarisCircuitBreakerAutoConfiguration.java
@@ -21,7 +21,6 @@ import java.util.ArrayList;
import java.util.List;
import com.tencent.cloud.polaris.circuitbreaker.PolarisCircuitBreakerFactory;
-import com.tencent.cloud.polaris.circuitbreaker.beanprocessor.LoadBalancerInterceptorBeanPostProcessor;
import com.tencent.cloud.polaris.circuitbreaker.common.CircuitBreakerConfigModifier;
import com.tencent.cloud.polaris.circuitbreaker.reporter.CircuitBreakerPlugin;
import com.tencent.cloud.polaris.circuitbreaker.reporter.ExceptionCircuitBreakerReporter;
@@ -32,7 +31,6 @@ import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
@@ -92,10 +90,6 @@ public class PolarisCircuitBreakerAutoConfiguration {
return new CircuitBreakerConfigModifier(properties, polarisCircuitBreakerProperties);
}
- @Bean
- @ConditionalOnClass(name = "org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor")
- public LoadBalancerInterceptorBeanPostProcessor loadBalancerInterceptorBeanPostProcessor() {
- return new LoadBalancerInterceptorBeanPostProcessor();
- }
+
}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisLoadBalancerInterceptor.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisLoadBalancerInterceptor.java
deleted file mode 100644
index fbf077f6f..000000000
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisLoadBalancerInterceptor.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Tencent is pleased to support the open source community by making spring-cloud-tencent available.
- *
- * Copyright (C) 2021 Tencent. 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.resttemplate;
-
-import java.io.IOException;
-import java.net.URI;
-
-import com.tencent.cloud.rpc.enhancement.instrument.resttemplate.EnhancedRestTemplateWrapInterceptor;
-import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
-
-import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
-import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
-import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestFactory;
-import org.springframework.http.HttpRequest;
-import org.springframework.http.client.ClientHttpRequestExecution;
-import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.util.Assert;
-
-/**
- * PolarisLoadBalancerInterceptor is a wrapper of LoadBalancerInterceptor.
- *
- * @author Shedfree Wu
- */
-public class PolarisLoadBalancerInterceptor extends LoadBalancerInterceptor {
-
- private final LoadBalancerClient loadBalancer;
- private final LoadBalancerRequestFactory requestFactory;
-
- private final EnhancedPluginRunner enhancedPluginRunner;
-
- public PolarisLoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory,
- EnhancedPluginRunner enhancedPluginRunner) {
- super(loadBalancer, requestFactory);
- this.loadBalancer = loadBalancer;
- this.requestFactory = requestFactory;
- this.enhancedPluginRunner = enhancedPluginRunner;
- }
-
- @Override
- public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
- final URI originalUri = request.getURI();
- String peerServiceName = originalUri.getHost();
- Assert.state(peerServiceName != null,
- "Request URI does not contain a valid hostname: " + originalUri);
-
- if (enhancedPluginRunner != null) {
- EnhancedRestTemplateWrapInterceptor enhancedRestTemplateWrapInterceptor = new EnhancedRestTemplateWrapInterceptor(enhancedPluginRunner, loadBalancer);
- return enhancedRestTemplateWrapInterceptor.intercept(request, peerServiceName, this.requestFactory.createRequest(request, body, execution));
- }
- else {
- return super.intercept(request, body, execution);
- }
- }
-}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisCircuitBreakerHttpResponseTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisCircuitBreakerHttpResponseTest.java
index 3e8380787..806c7b626 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisCircuitBreakerHttpResponseTest.java
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisCircuitBreakerHttpResponseTest.java
@@ -39,7 +39,7 @@ public class PolarisCircuitBreakerHttpResponseTest {
void testConstructorWithCodeOnly() throws IOException {
PolarisCircuitBreakerHttpResponse response = new PolarisCircuitBreakerHttpResponse(200);
- Assertions.assertEquals(200, response.getRawStatusCode());
+ Assertions.assertEquals(200, response.getStatusCode().value());
Assertions.assertNotNull(response.getHeaders());
Assertions.assertTrue(response.getHeaders().isEmpty());
Assertions.assertNull(response.getBody());
@@ -50,7 +50,7 @@ public class PolarisCircuitBreakerHttpResponseTest {
String body = "test body";
PolarisCircuitBreakerHttpResponse response = new PolarisCircuitBreakerHttpResponse(200, body);
- Assertions.assertEquals(200, response.getRawStatusCode());
+ Assertions.assertEquals(200, response.getStatusCode().value());
Assertions.assertNotNull(response.getHeaders());
Assertions.assertTrue(response.getHeaders().isEmpty());
Assertions.assertNotNull(response.getBody());
@@ -65,7 +65,7 @@ public class PolarisCircuitBreakerHttpResponseTest {
PolarisCircuitBreakerHttpResponse response = new PolarisCircuitBreakerHttpResponse(200, headers, body);
- Assertions.assertEquals(200, response.getRawStatusCode());
+ Assertions.assertEquals(200, response.getStatusCode().value());
Assertions.assertNotNull(response.getHeaders());
Assertions.assertEquals(2, response.getHeaders().size());
Assertions.assertTrue(response.getHeaders().containsKey("Content-Type"));
@@ -81,7 +81,7 @@ public class PolarisCircuitBreakerHttpResponseTest {
PolarisCircuitBreakerHttpResponse response = new PolarisCircuitBreakerHttpResponse(fallbackInfo);
- Assertions.assertEquals(200, response.getRawStatusCode());
+ Assertions.assertEquals(200, response.getStatusCode().value());
Assertions.assertEquals(fallbackInfo, response.getFallbackInfo());
Assertions.assertNotNull(response.getHeaders());
Assertions.assertTrue(response.getHeaders().containsKey("Content-Type"));
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisLoadBalancerInterceptorTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisLoadBalancerInterceptorTest.java
deleted file mode 100644
index 50f7b9ae6..000000000
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/instrument/resttemplate/PolarisLoadBalancerInterceptorTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Tencent is pleased to support the open source community by making spring-cloud-tencent available.
- *
- * Copyright (C) 2021 Tencent. 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.resttemplate;
-
-import java.io.IOException;
-import java.net.URI;
-import java.util.Objects;
-
-import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
-import org.junit.jupiter.api.Assertions;
-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.client.loadbalancer.LoadBalancerClient;
-import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestFactory;
-import org.springframework.http.HttpRequest;
-import org.springframework.http.client.ClientHttpRequestExecution;
-import org.springframework.http.client.ClientHttpResponse;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-/**
- * Test for ${@link PolarisLoadBalancerInterceptor}.
- *
- * @author Shedfree Wu
- */
-@ExtendWith(MockitoExtension.class)
-class PolarisLoadBalancerInterceptorTest {
-
- @Mock
- private LoadBalancerClient loadBalancer;
-
- @Mock
- private LoadBalancerRequestFactory requestFactory;
-
- @Mock
- private EnhancedPluginRunner enhancedPluginRunner;
-
- @Mock
- private HttpRequest request;
-
- @Mock
- private ClientHttpRequestExecution execution;
-
- private PolarisLoadBalancerInterceptor interceptor;
- private byte[] body;
-
- @BeforeEach
- void setUp() {
- body = "test body".getBytes();
- }
-
- @Test
- void testInterceptWithEnhancedPlugin() throws IOException {
- // Arrange
- ClientHttpResponse mockResponse = mock(ClientHttpResponse.class);
- interceptor = new PolarisLoadBalancerInterceptor(loadBalancer, requestFactory, enhancedPluginRunner);
- URI uri = URI.create("http://test-service/path");
- when(request.getURI()).thenReturn(uri);
- when(loadBalancer.execute(any(), any())).thenReturn(mockResponse);
-
- // Act
- ClientHttpResponse response = interceptor.intercept(request, body, execution);
-
- // Assert
- Assertions.assertTrue(Objects.equals(mockResponse, response) || response instanceof PolarisCircuitBreakerHttpResponse);
- }
-
- @Test
- void testInterceptWithoutEnhancedPlugin() throws IOException {
- // Arrange
- ClientHttpResponse mockResponse = mock(ClientHttpResponse.class);
- interceptor = new PolarisLoadBalancerInterceptor(loadBalancer, requestFactory, null);
- URI uri = URI.create("http://test-service/path");
- when(request.getURI()).thenReturn(uri);
- when(loadBalancer.execute(any(), any())).thenReturn(mockResponse);
-
- // Act
- ClientHttpResponse response = interceptor.intercept(request, body, execution);
-
- // Assert
- Assertions.assertEquals(mockResponse, response);
- }
-
- @Test
- void testInterceptWithInvalidUri() {
- // Arrange
- interceptor = new PolarisLoadBalancerInterceptor(loadBalancer, requestFactory, enhancedPluginRunner);
- when(request.getURI()).thenReturn(URI.create("http:///path")); // Invalid URI without host
-
- // Act & Assert
- Exception exception = Assertions.assertThrows(IllegalStateException.class, () -> {
- interceptor.intercept(request, body, execution);
- });
- Assertions.assertTrue(exception.getMessage().contains("Request URI does not contain a valid hostname"));
- }
-
- @Test
- void testConstructor() {
- // Act
- interceptor = new PolarisLoadBalancerInterceptor(loadBalancer, requestFactory, enhancedPluginRunner);
-
- // Assert
- Assertions.assertNotNull(interceptor);
- }
-}
diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/eager/instrument/feign/FeignEagerLoadSmartLifecycle.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/eager/instrument/feign/FeignEagerLoadSmartLifecycle.java
index da1bbbaca..327edb59b 100644
--- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/eager/instrument/feign/FeignEagerLoadSmartLifecycle.java
+++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/eager/instrument/feign/FeignEagerLoadSmartLifecycle.java
@@ -19,6 +19,7 @@ package com.tencent.cloud.polaris.eager.instrument.feign;
import java.lang.reflect.Field;
import java.lang.reflect.Proxy;
+import java.net.URI;
import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClient;
import com.tencent.cloud.polaris.discovery.reactive.PolarisReactiveDiscoveryClient;
@@ -60,18 +61,24 @@ public class FeignEagerLoadSmartLifecycle implements SmartLifecycle {
// if feignClient contains url, it doesn't need to eager load.
if (StringUtils.isEmpty(feignClient.url())) {
// support variables and default values.
- String feignName = hardCodedTarget.name();
- LOG.info("[{}] eager-load start", feignName);
+ String url = hardCodedTarget.name();
+ // refer to FeignClientFactoryBean, convert to URL, then take the host as the service name.
+ if (!url.startsWith("http://") && !url.startsWith("https://")) {
+ url = "http://" + url;
+ }
+ String serviceName = URI.create(url).getHost();
+
+ LOG.info("[{}] eager-load start", serviceName);
if (polarisDiscoveryClient != null) {
- polarisDiscoveryClient.getInstances(feignName);
+ polarisDiscoveryClient.getInstances(serviceName);
}
else if (polarisReactiveDiscoveryClient != null) {
- polarisReactiveDiscoveryClient.getInstances(feignName).subscribe();
+ polarisReactiveDiscoveryClient.getInstances(serviceName).subscribe();
}
else {
- LOG.warn("[{}] no discovery client found.", feignName);
+ LOG.warn("[{}] no discovery client found.", serviceName);
}
- LOG.info("[{}] eager-load end", feignName);
+ LOG.info("[{}] eager-load end", serviceName);
}
}
}
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/pom.xml b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/pom.xml
index ef439ca41..64bbb5991 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/pom.xml
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/pom.xml
@@ -19,30 +19,6 @@
spring-cloud-starter-tencent-polaris-config
-
- commons-codec
- commons-codec
-
-
-
- commons-beanutils
- commons-beanutils
- 1.11.0
-
-
-
- org.bitbucket.b_c
- jose4j
- 0.9.4
-
-
-
- com.tencent
- tencentsm-crypto
- 1.9.1
- true
-
-
com.tencent.cloud
spring-cloud-starter-tencent-polaris-discovery
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/cloud/plugin/gateway/context/ContextGatewayPropertiesManager.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/cloud/plugin/gateway/context/ContextGatewayPropertiesManager.java
index 0d624f8be..38ecd8af6 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/cloud/plugin/gateway/context/ContextGatewayPropertiesManager.java
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/cloud/plugin/gateway/context/ContextGatewayPropertiesManager.java
@@ -41,9 +41,9 @@ import com.tencent.tsf.gateway.core.model.PluginDetail;
import com.tencent.tsf.gateway.core.model.PluginInfo;
import com.tencent.tsf.gateway.core.model.PluginInstanceInfo;
import com.tencent.tsf.gateway.core.util.PluginUtil;
-import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import shade.polaris.org.apache.commons.beanutils.BeanUtils;
import org.springframework.util.AntPathMatcher;
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/plugin/JwtGatewayPlugin.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/plugin/JwtGatewayPlugin.java
index aaba5aadf..9117aa817 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/plugin/JwtGatewayPlugin.java
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/plugin/JwtGatewayPlugin.java
@@ -31,17 +31,16 @@ import com.tencent.tsf.gateway.core.exception.TsfGatewayException;
import com.tencent.tsf.gateway.core.model.ClaimMapping;
import com.tencent.tsf.gateway.core.model.JwtPlugin;
import com.tencent.tsf.gateway.core.model.PluginPayload;
-import org.jose4j.jwa.AlgorithmConstraints;
-import org.jose4j.jwa.AlgorithmConstraints.ConstraintType;
-import org.jose4j.jwk.PublicJsonWebKey;
-import org.jose4j.jwt.JwtClaims;
-import org.jose4j.jwt.MalformedClaimException;
-import org.jose4j.jwt.consumer.InvalidJwtException;
-import org.jose4j.jwt.consumer.JwtConsumer;
-import org.jose4j.jwt.consumer.JwtConsumerBuilder;
-import org.jose4j.lang.JoseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import shade.polaris.org.jose4j.jwa.AlgorithmConstraints;
+import shade.polaris.org.jose4j.jwk.PublicJsonWebKey;
+import shade.polaris.org.jose4j.jwt.JwtClaims;
+import shade.polaris.org.jose4j.jwt.MalformedClaimException;
+import shade.polaris.org.jose4j.jwt.consumer.InvalidJwtException;
+import shade.polaris.org.jose4j.jwt.consumer.JwtConsumer;
+import shade.polaris.org.jose4j.jwt.consumer.JwtConsumerBuilder;
+import shade.polaris.org.jose4j.lang.JoseException;
/**
@@ -60,6 +59,7 @@ public class JwtGatewayPlugin implements IGatewayPlugin {
Map parameterMap = tsfGatewayRequest.getParameterMap();
String tokenBaggagePosition = pluginInfo.getTokenBaggagePosition();
if (Position.fromString(tokenBaggagePosition) == null) {
+ logger.error("tokenBaggagePosition is wrong, tokenBaggagePosition: {}, tsfGatewayRequest: {}", tokenBaggagePosition, tsfGatewayRequest);
throw new TsfGatewayException(TsfGatewayError.GATEWAY_AUTH_FAILED, "tokenBaggagePosition is wrong");
}
String idToken;
@@ -69,11 +69,13 @@ public class JwtGatewayPlugin implements IGatewayPlugin {
else {
//queryParam中取
if (parameterMap.get(pluginInfo.getTokenKeyName()) == null || parameterMap.get(pluginInfo.getTokenKeyName()).length == 0) {
+ logger.error("idToken is empty, tsfGatewayRequest: {}", tsfGatewayRequest);
throw new TsfGatewayException(TsfGatewayError.GATEWAY_AUTH_FAILED, "idToken is empty");
}
idToken = parameterMap.get(pluginInfo.getTokenKeyName())[0];
}
if (StringUtils.isEmpty(idToken)) {
+ logger.error("idToken is empty, tsfGatewayRequest: {}", tsfGatewayRequest);
throw new TsfGatewayException(TsfGatewayError.GATEWAY_AUTH_FAILED, "idToken is empty");
}
@@ -95,7 +97,7 @@ public class JwtGatewayPlugin implements IGatewayPlugin {
.setAllowedClockSkewInSeconds(30) // allow some leeway in validating time based claims to account for clock skew
.setRequireSubject() // the JWT must have a subject claim
.setVerificationKey(jwk.getPublicKey())
- .setJwsAlgorithmConstraints(new AlgorithmConstraints(ConstraintType.WHITELIST, jwk.getAlgorithm()))
+ .setJwsAlgorithmConstraints(new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST, jwk.getAlgorithm()))
// ignore audience
.setSkipDefaultAudienceValidation()
.build(); // create the JwtConsumer instance
@@ -114,7 +116,7 @@ public class JwtGatewayPlugin implements IGatewayPlugin {
.getValueInMillis();
String msg = String
.format("JWT expired at (%d)", expirationTime);
- logger.info(msg);
+ logger.error(msg);
throw new TsfGatewayException(TsfGatewayError.GATEWAY_AUTH_ERROR, msg);
}
catch (MalformedClaimException e1) {
@@ -122,7 +124,7 @@ public class JwtGatewayPlugin implements IGatewayPlugin {
}
}
- logger.warn("Invalid JWT! ", e);
+ logger.warn("Invalid JWT! tsfGatewayRequest:{}, error:{}", tsfGatewayRequest, e.getMessage());
throw new TsfGatewayException(TsfGatewayError.GATEWAY_AUTH_ERROR, "Invalid JWT");
}
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/util/IdGenerator.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/util/IdGenerator.java
index 789e9e485..95d33d3c2 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/util/IdGenerator.java
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/util/IdGenerator.java
@@ -19,7 +19,7 @@ package com.tencent.tsf.gateway.core.util;
import java.util.UUID;
-import org.apache.commons.codec.binary.Base64;
+import shade.polaris.org.apache.commons.codec.binary.Base64;
/**
* @author kysonli
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/util/SM3Util.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/util/SM3Util.java
deleted file mode 100644
index 0162eb9ae..000000000
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/util/SM3Util.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Tencent is pleased to support the open source community by making spring-cloud-tencent available.
- *
- * Copyright (C) 2021 Tencent. 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.gateway.core.util;
-
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Security;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-
-import com.tencent.crypto.provider.SMCSProvider;
-import org.apache.commons.codec.binary.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * 国密加解密工具类.
- * @author xfenggeng
- * @date 2021-10-11 9:53
- */
-public final class SM3Util {
-
- private static final String SM3_ALGORITHM = "SM3";
- private static final String SM3_ALGORITHM_HMAC = "SM3HMac";
- private static final String SMCS_PROVIDER = "SMCSProvider";
- private static final Logger logger = LoggerFactory.getLogger(SM3Util.class);
-
- static {
- try {
- Security.addProvider(new SMCSProvider());
- }
- catch (Throwable t) {
- logger.warn("load SMCSProvider error:{}", t.getMessage());
- }
- }
-
- private SM3Util() {
-
- }
-
- /**
- * 计算SM3摘要.
- * @param content 原文
- * @return 摘要
- */
- public static byte[] hmacSm3(String secretKey, String content) {
- try {
- // Get Mac instance
- Mac sm3HMac = Mac.getInstance(SM3_ALGORITHM_HMAC, SMCS_PROVIDER);
- // Initialize Mac with a specified key
- SecretKeySpec keySpec = new SecretKeySpec(StringUtils.getBytesUtf8(secretKey), SM3_ALGORITHM);
- sm3HMac.init(keySpec);
- // Generate MAC for the specified message
- byte[] mac = sm3HMac.doFinal(StringUtils.getBytesUtf8(content));
- return mac;
- }
- catch (NoSuchAlgorithmException e) {
- throw new IllegalArgumentException(e);
- }
- catch (NoSuchProviderException e) {
- throw new IllegalArgumentException(e);
- }
- catch (InvalidKeyException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
-}
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/util/TsfSignUtil.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/util/TsfSignUtil.java
index 87fff0acf..bd2a93e88 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/util/TsfSignUtil.java
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-gateway-plugin/src/main/java/com/tencent/tsf/gateway/core/util/TsfSignUtil.java
@@ -18,10 +18,10 @@
package com.tencent.tsf.gateway.core.util;
import com.tencent.tsf.gateway.core.constant.TsfAlgType;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.digest.HmacUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import shade.polaris.org.apache.commons.codec.binary.Base64;
+import shade.polaris.org.apache.commons.codec.digest.HmacUtils;
/**
@@ -60,9 +60,6 @@ public final class TsfSignUtil {
case HMAC_SHA_512:
serverSignBytes = HmacUtils.hmacSha512(secretKey, digestValue);
break;
- case HMAC_SM3:
- serverSignBytes = SM3Util.hmacSm3(secretKey, digestValue);
- break;
default:
throw new UnsupportedOperationException("不支持的鉴权算法: " + algType);
}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/beanprocessor/BlockingLoadBalancerClientBeanPostProcessor.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/beanprocessor/BlockingLoadBalancerClientBeanPostProcessor.java
new file mode 100644
index 000000000..f48144b22
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/beanprocessor/BlockingLoadBalancerClientBeanPostProcessor.java
@@ -0,0 +1,66 @@
+/*
+ * Tencent is pleased to support the open source community by making spring-cloud-tencent available.
+ *
+ * Copyright (C) 2021 Tencent. 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.rpc.enhancement.beanprocessor;
+
+import com.tencent.cloud.rpc.enhancement.instrument.resttemplate.PolarisBlockingLoadBalancerClient;
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer;
+import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
+import org.springframework.core.Ordered;
+import org.springframework.lang.NonNull;
+
+/**
+ * BlockingLoadBalancerClientBeanPostProcessor is used to wrap the default BlockingLoadBalancerClient implementation and returns a custom PolarisBlockingLoadBalancerClient.
+ *
+ * @author Shedfree Wu
+ */
+public class BlockingLoadBalancerClientBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware, Ordered {
+ /**
+ * The order of the bean post processor. If user wants to wrap it(CustomBlockingLoadBalancerClient -> PolarisBlockingLoadBalancerClient), CustomBlockingLoadBalancerClientBeanPostProcessor's order should be bigger than ${@link ORDER}.
+ */
+ public static final int ORDER = 0;
+
+ private BeanFactory factory;
+
+ @Override
+ public void setBeanFactory(@NonNull BeanFactory beanFactory) throws BeansException {
+ this.factory = beanFactory;
+ }
+
+ @Override
+ public Object postProcessBeforeInitialization(@NonNull Object bean, @NonNull String beanName) throws BeansException {
+ if (bean instanceof BlockingLoadBalancerClient) {
+ BlockingLoadBalancerClient delegate = (BlockingLoadBalancerClient) bean;
+ ReactiveLoadBalancer.Factory requestFactory = this.factory.getBean(ReactiveLoadBalancer.Factory.class);
+ EnhancedPluginRunner pluginRunner = this.factory.getBean(EnhancedPluginRunner.class);
+ return new PolarisBlockingLoadBalancerClient(requestFactory, delegate, pluginRunner);
+ }
+ return bean;
+ }
+
+ @Override
+ public int getOrder() {
+ return ORDER;
+ }
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java
index 96b886a91..edda6e380 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java
@@ -23,6 +23,7 @@ import java.util.List;
import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled;
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
+import com.tencent.cloud.rpc.enhancement.beanprocessor.BlockingLoadBalancerClientBeanPostProcessor;
import com.tencent.cloud.rpc.enhancement.instrument.feign.EnhancedFeignBeanPostProcessor;
import com.tencent.cloud.rpc.enhancement.instrument.feign.PolarisLoadBalancerFeignRequestTransformer;
import com.tencent.cloud.rpc.enhancement.instrument.filter.EnhancedReactiveFilter;
@@ -114,6 +115,12 @@ public class RpcEnhancementAutoConfiguration {
return new ExceptionPolarisReporter(properties, polarisSDKContextManager.getConsumerAPI());
}
+ @Bean
+ @ConditionalOnClass(name = "org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor")
+ public BlockingLoadBalancerClientBeanPostProcessor loadBalancerInterceptorBeanPostProcessor() {
+ return new BlockingLoadBalancerClientBeanPostProcessor();
+ }
+
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
protected static class RpcEnhancementServletFilterConfig {
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/instrument/resttemplate/EnhancedRestTemplateWrapInterceptor.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/instrument/resttemplate/EnhancedRestTemplateWrapInterceptor.java
index 2659ce340..cb29597f3 100644
--- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/instrument/resttemplate/EnhancedRestTemplateWrapInterceptor.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/instrument/resttemplate/EnhancedRestTemplateWrapInterceptor.java
@@ -58,24 +58,24 @@ public class EnhancedRestTemplateWrapInterceptor {
}
- public ClientHttpResponse intercept(HttpRequest request, String serviceId,
- LoadBalancerRequest loadBalancerRequest) throws IOException {
+ public T intercept(HttpRequest httpRequest, String serviceId, ServiceInstance serviceInstance,
+ LoadBalancerRequest loadBalancerRequest) throws IOException {
EnhancedPluginContext enhancedPluginContext = new EnhancedPluginContext();
- URI serviceUrl = request.getURI();
- if (request instanceof ServiceRequestWrapper) {
- serviceUrl = ((ServiceRequestWrapper) request).getRequest().getURI();
+ URI serviceUrl = httpRequest.getURI();
+ if (httpRequest instanceof ServiceRequestWrapper) {
+ serviceUrl = ((ServiceRequestWrapper) httpRequest).getRequest().getURI();
}
EnhancedRequestContext enhancedRequestContext = EnhancedRequestContext.builder()
- .httpHeaders(request.getHeaders())
- .httpMethod(request.getMethod())
- .url(request.getURI())
+ .httpHeaders(httpRequest.getHeaders())
+ .httpMethod(httpRequest.getMethod())
+ .url(httpRequest.getURI())
.serviceUrl(serviceUrl)
.build();
enhancedPluginContext.setRequest(enhancedRequestContext);
- enhancedPluginContext.setOriginRequest(request);
+ enhancedPluginContext.setOriginRequest(httpRequest);
enhancedPluginContext.setLocalServiceInstance(pluginRunner.getLocalServiceInstance());
@@ -85,16 +85,27 @@ public class EnhancedRestTemplateWrapInterceptor {
pluginRunner.run(EnhancedPluginType.Client.PRE, enhancedPluginContext);
startMillis = System.currentTimeMillis();
- ClientHttpResponse response = delegate.execute(serviceId, loadBalancerRequest);
+ T response = null;
+ // retry rest template, serviceInstance is not null
+ if (serviceInstance != null) {
+ response = delegate.execute(serviceId, serviceInstance, loadBalancerRequest);
+ }
+ else {
+ response = delegate.execute(serviceId, loadBalancerRequest);
+ }
// get target instance after execute
enhancedPluginContext.setTargetServiceInstance((ServiceInstance) MetadataContextHolder.get()
- .getLoadbalancerMetadata().get(LOAD_BALANCER_SERVICE_INSTANCE), request.getURI());
+ .getLoadbalancerMetadata().get(LOAD_BALANCER_SERVICE_INSTANCE), httpRequest.getURI());
enhancedPluginContext.setDelay(System.currentTimeMillis() - startMillis);
- EnhancedResponseContext enhancedResponseContext = EnhancedResponseContext.builder()
- .httpStatus(response.getRawStatusCode())
- .httpHeaders(response.getHeaders())
- .build();
+
+ EnhancedResponseContext.EnhancedContextResponseBuilder enhancedResponseContextBuilder = EnhancedResponseContext.builder();
+ if (response instanceof ClientHttpResponse) {
+ enhancedResponseContextBuilder.httpStatus(((ClientHttpResponse) response).getStatusCode().value());
+ enhancedResponseContextBuilder.httpHeaders(((ClientHttpResponse) response).getHeaders());
+ }
+ EnhancedResponseContext enhancedResponseContext = enhancedResponseContextBuilder.build();
+
enhancedPluginContext.setResponse(enhancedResponseContext);
// Run post enhanced plugins.
@@ -114,7 +125,7 @@ public class EnhancedRestTemplateWrapInterceptor {
if (existFallback) {
Object fallbackResponse = fallbackResponseValue.getObjectValue().orElse(null);
if (fallbackResponse instanceof ClientHttpResponse) {
- return (ClientHttpResponse) fallbackResponse;
+ return (T) fallbackResponse;
}
}
throw callAbortedException;
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/instrument/resttemplate/PolarisBlockingLoadBalancerClient.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/instrument/resttemplate/PolarisBlockingLoadBalancerClient.java
new file mode 100644
index 000000000..aa9a89774
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/instrument/resttemplate/PolarisBlockingLoadBalancerClient.java
@@ -0,0 +1,74 @@
+/*
+ * Tencent is pleased to support the open source community by making spring-cloud-tencent available.
+ *
+ * Copyright (C) 2021 Tencent. 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.rpc.enhancement.instrument.resttemplate;
+
+import java.io.IOException;
+
+import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
+
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerUtils;
+import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer;
+import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
+import org.springframework.http.HttpRequest;
+
+/**
+ * PolarisBlockingLoadBalancerClient is a wrapper of BlockingLoadBalancerClient.
+ *
+ * @author Shedfree Wu
+ */
+public class PolarisBlockingLoadBalancerClient extends BlockingLoadBalancerClient {
+
+ private BlockingLoadBalancerClient delegate;
+
+ private final EnhancedPluginRunner enhancedPluginRunner;
+
+ public PolarisBlockingLoadBalancerClient(ReactiveLoadBalancer.Factory loadBalancerClientFactory,
+ BlockingLoadBalancerClient delegate, EnhancedPluginRunner enhancedPluginRunner) {
+ super(loadBalancerClientFactory);
+ this.delegate = delegate;
+ this.enhancedPluginRunner = enhancedPluginRunner;
+ }
+
+ /**
+ * common rest template.
+ */
+ @Override
+ public T execute(String serviceId, LoadBalancerRequest request) throws IOException {
+ HttpRequest httpRequest = LoadBalancerUtils.getHttpRequestIfAvailable(request);
+ if (httpRequest == null || enhancedPluginRunner == null) {
+ return delegate.execute(serviceId, request);
+ }
+ EnhancedRestTemplateWrapInterceptor enhancedRestTemplateWrapInterceptor = new EnhancedRestTemplateWrapInterceptor(enhancedPluginRunner, delegate);
+ return enhancedRestTemplateWrapInterceptor.intercept(httpRequest, serviceId, null, request);
+ }
+
+ /**
+ * retry rest template.
+ */
+ @Override
+ public T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest request) throws IOException {
+ HttpRequest httpRequest = LoadBalancerUtils.getHttpRequestIfAvailable(LoadBalancerUtils.getDelegateLoadBalancerRequestIfAvailable(request));
+ if (httpRequest == null || serviceInstance == null || enhancedPluginRunner == null) {
+ return delegate.execute(serviceId, serviceInstance, request);
+ }
+ EnhancedRestTemplateWrapInterceptor enhancedRestTemplateWrapInterceptor = new EnhancedRestTemplateWrapInterceptor(enhancedPluginRunner, delegate);
+ return enhancedRestTemplateWrapInterceptor.intercept(httpRequest, serviceId, serviceInstance, request);
+ }
+}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUtils.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUtils.java
new file mode 100644
index 000000000..df459747f
--- /dev/null
+++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUtils.java
@@ -0,0 +1,58 @@
+package org.springframework.cloud.client.loadbalancer;
+
+import java.lang.reflect.Field;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.http.HttpRequest;
+
+public final class LoadBalancerUtils {
+
+ private static final Logger logger = LoggerFactory.getLogger(LoadBalancerUtils.class);
+
+ private LoadBalancerUtils() {
+ }
+
+ /**
+ * if request is a BlockingLoadBalancerRequest, return its HttpRequest.
+ */
+ public static HttpRequest getHttpRequestIfAvailable(LoadBalancerRequest> request) {
+ if (request instanceof BlockingLoadBalancerRequest) {
+ BlockingLoadBalancerRequest blockingRequest = (BlockingLoadBalancerRequest) request;
+ return blockingRequest.getHttpRequest();
+ }
+ else {
+ if (logger.isDebugEnabled()) {
+ logger.debug("LoadBalancerRequest is not a BlockingLoadBalancerRequest, request:{}", request);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * if request is a LoadBalancerRequestAdapter(RetryLoadBalancerInterceptor), return its delegate.
+ */
+ public static LoadBalancerRequest> getDelegateLoadBalancerRequestIfAvailable(LoadBalancerRequest> request) {
+ if (!(request instanceof LoadBalancerRequestAdapter)) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("LoadBalancerRequest is not a LoadBalancerRequestAdapter, request:{}", request);
+ }
+ return request;
+ }
+
+ try {
+ Field delegateField = LoadBalancerRequestAdapter.class.getDeclaredField("delegate");
+ delegateField.setAccessible(true);
+ return (LoadBalancerRequest>) delegateField.get(request);
+ }
+ catch (Exception e) {
+ // ignore
+ if (logger.isDebugEnabled()) {
+ logger.debug("Failed to get delegate from LoadBalancerRequestAdapter, request:{}", request, e);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/beanprocessor/LoadBalancerInterceptorBeanPostProcessorTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/beanprocessor/BlockingLoadBalancerClientBeanPostProcessorTest.java
similarity index 51%
rename from spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/beanprocessor/LoadBalancerInterceptorBeanPostProcessorTest.java
rename to spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/beanprocessor/BlockingLoadBalancerClientBeanPostProcessorTest.java
index 6e5f55d50..0d50adcfd 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/beanprocessor/LoadBalancerInterceptorBeanPostProcessorTest.java
+++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/beanprocessor/BlockingLoadBalancerClientBeanPostProcessorTest.java
@@ -15,9 +15,8 @@
* specific language governing permissions and limitations under the License.
*/
-package com.tencent.cloud.polaris.circuitbreaker.beanprocessor;
+package com.tencent.cloud.rpc.enhancement.beanprocessor;
-import com.tencent.cloud.polaris.circuitbreaker.instrument.resttemplate.PolarisLoadBalancerInterceptor;
import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -27,19 +26,16 @@ import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
-import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor;
import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestFactory;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
- * Test for ${@link LoadBalancerInterceptorBeanPostProcessor}.
+ * Test for ${@link BlockingLoadBalancerClientBeanPostProcessor}.
*
* @author Shedfree Wu
*/
-class LoadBalancerInterceptorBeanPostProcessorTest {
+class BlockingLoadBalancerClientBeanPostProcessorTest {
@Mock
private BeanFactory beanFactory;
@@ -53,12 +49,12 @@ class LoadBalancerInterceptorBeanPostProcessorTest {
@Mock
private EnhancedPluginRunner pluginRunner;
- private LoadBalancerInterceptorBeanPostProcessor processor;
+ private BlockingLoadBalancerClientBeanPostProcessor processor;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
- processor = new LoadBalancerInterceptorBeanPostProcessor();
+ processor = new BlockingLoadBalancerClientBeanPostProcessor();
processor.setBeanFactory(beanFactory);
// Setup mock behavior
@@ -67,22 +63,6 @@ class LoadBalancerInterceptorBeanPostProcessorTest {
when(beanFactory.getBean(EnhancedPluginRunner.class)).thenReturn(pluginRunner);
}
- @Test
- void testPostProcessBeforeInitializationWithLoadBalancerInterceptor() {
- // Arrange
- LoadBalancerInterceptor originalInterceptor = mock(LoadBalancerInterceptor.class);
- String beanName = "testBean";
-
- // Act
- Object result = processor.postProcessBeforeInitialization(originalInterceptor, beanName);
-
- // Assert
- Assertions.assertInstanceOf(PolarisLoadBalancerInterceptor.class, result);
- verify(beanFactory).getBean(LoadBalancerRequestFactory.class);
- verify(beanFactory).getBean(LoadBalancerClient.class);
- verify(beanFactory).getBean(EnhancedPluginRunner.class);
- }
-
@Test
void testPostProcessBeforeInitializationWithNonLoadBalancerInterceptor() {
// Arrange
@@ -102,26 +82,6 @@ class LoadBalancerInterceptorBeanPostProcessorTest {
int order = processor.getOrder();
// Assert
- Assertions.assertEquals(LoadBalancerInterceptorBeanPostProcessor.POLARIS_LOAD_BALANCER_INTERCEPTOR_POST_PROCESSOR_ORDER, order);
- }
-
- @Test
- void testSetBeanFactory() {
- // Arrange
- BeanFactory newBeanFactory = mock(BeanFactory.class);
- LoadBalancerInterceptorBeanPostProcessor newProcessor = new LoadBalancerInterceptorBeanPostProcessor();
-
- // Act
- newProcessor.setBeanFactory(newBeanFactory);
-
- // Assert
- // Verify the bean factory is set by trying to process a bean
- LoadBalancerInterceptor interceptor = mock(LoadBalancerInterceptor.class);
- when(newBeanFactory.getBean(LoadBalancerRequestFactory.class)).thenReturn(requestFactory);
- when(newBeanFactory.getBean(LoadBalancerClient.class)).thenReturn(loadBalancerClient);
- when(newBeanFactory.getBean(EnhancedPluginRunner.class)).thenReturn(pluginRunner);
-
- Object result = newProcessor.postProcessBeforeInitialization(interceptor, "testBean");
- Assertions.assertInstanceOf(PolarisLoadBalancerInterceptor.class, result);
+ Assertions.assertEquals(BlockingLoadBalancerClientBeanPostProcessor.ORDER, order);
}
}
diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/instrument/resttemplate/EnhancedRestTemplateWrapInterceptorTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/instrument/resttemplate/EnhancedRestTemplateWrapInterceptorTest.java
deleted file mode 100644
index fd7d99e08..000000000
--- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/instrument/resttemplate/EnhancedRestTemplateWrapInterceptorTest.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Tencent is pleased to support the open source community by making spring-cloud-tencent available.
- *
- * Copyright (C) 2021 Tencent. 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.rpc.enhancement.instrument.resttemplate;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-
-import com.tencent.cloud.common.constant.ContextConstant;
-import com.tencent.cloud.common.metadata.MetadataContextHolder;
-import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext;
-import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginRunner;
-import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType;
-import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
-import com.tencent.polaris.metadata.core.MetadataType;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.junit.jupiter.MockitoExtension;
-
-import org.springframework.cloud.client.ServiceInstance;
-import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
-import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest;
-import org.springframework.cloud.client.loadbalancer.ServiceRequestWrapper;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpRequest;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.client.ClientHttpResponse;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-/**
- * Test for {@link EnhancedRestTemplateWrapInterceptor}.
- *
- * @author Shedfree Wu
- */
-@ExtendWith(MockitoExtension.class)
-class EnhancedRestTemplateWrapInterceptorTest {
-
- @Mock
- private EnhancedPluginRunner pluginRunner;
-
- @Mock
- private LoadBalancerClient delegate;
-
- @Mock
- private HttpRequest request;
-
- @Mock
- private ClientHttpResponse response;
-
- @Mock
- private ServiceRequestWrapper serviceRequestWrapper;
-
- @Mock
- private ServiceInstance localServiceInstance;
-
- private EnhancedRestTemplateWrapInterceptor interceptor;
-
- @BeforeEach
- void setUp() {
- MockitoAnnotations.openMocks(this);
- interceptor = new EnhancedRestTemplateWrapInterceptor(pluginRunner, delegate);
- }
-
- @Test
- void testInterceptWithNormalRequest() throws IOException {
- // Arrange
- URI uri = URI.create("http://test-service/api");
- HttpHeaders headers = new HttpHeaders();
- headers.add("test-header", "test-value");
-
- when(request.getURI()).thenReturn(uri);
- when(request.getHeaders()).thenReturn(headers);
- when(request.getMethod()).thenReturn(HttpMethod.GET);
- when(pluginRunner.getLocalServiceInstance()).thenReturn(localServiceInstance);
- when(delegate.execute(any(), any())).thenReturn(response);
- when(response.getRawStatusCode()).thenReturn(200);
- when(response.getHeaders()).thenReturn(new HttpHeaders());
-
- // Act
- interceptor.intercept(request, "test-service", mock(LoadBalancerRequest.class));
-
- // Assert
- verify(pluginRunner).run(eq(EnhancedPluginType.Client.PRE), any(EnhancedPluginContext.class));
-
- // Verify context setup
- ArgumentCaptor contextCaptor = ArgumentCaptor.forClass(EnhancedPluginContext.class);
- verify(pluginRunner).run(eq(EnhancedPluginType.Client.PRE), contextCaptor.capture());
-
- EnhancedPluginContext capturedContext = contextCaptor.getValue();
- Assertions.assertEquals(uri, capturedContext.getRequest().getUrl());
- Assertions.assertEquals(uri, capturedContext.getRequest().getServiceUrl());
- Assertions.assertEquals(headers, capturedContext.getRequest().getHttpHeaders());
- Assertions.assertEquals(HttpMethod.GET, capturedContext.getRequest().getHttpMethod());
- Assertions.assertEquals(localServiceInstance, capturedContext.getLocalServiceInstance());
- }
-
- @Test
- void testInterceptWithServiceRequestWrapper() throws IOException {
- // Arrange
- URI originalUri = URI.create("http://original-service/api");
- URI wrappedUri = URI.create("http://wrapped-service/api");
- HttpHeaders headers = new HttpHeaders();
-
- when(serviceRequestWrapper.getURI()).thenReturn(wrappedUri);
- when(serviceRequestWrapper.getRequest()).thenReturn(request);
- when(serviceRequestWrapper.getHeaders()).thenReturn(headers);
- when(serviceRequestWrapper.getMethod()).thenReturn(HttpMethod.POST);
- when(request.getURI()).thenReturn(originalUri);
- when(pluginRunner.getLocalServiceInstance()).thenReturn(localServiceInstance);
- when(delegate.execute(any(), any())).thenReturn(response);
- when(response.getRawStatusCode()).thenReturn(200);
- when(response.getHeaders()).thenReturn(new HttpHeaders());
-
- // Act
- interceptor.intercept(serviceRequestWrapper, "test-service", mock(LoadBalancerRequest.class));
-
- // Assert
- verify(pluginRunner).run(eq(EnhancedPluginType.Client.PRE), any(EnhancedPluginContext.class));
-
- ArgumentCaptor contextCaptor = ArgumentCaptor.forClass(EnhancedPluginContext.class);
- verify(pluginRunner).run(eq(EnhancedPluginType.Client.PRE), contextCaptor.capture());
-
- EnhancedPluginContext capturedContext = contextCaptor.getValue();
- Assertions.assertEquals(wrappedUri, capturedContext.getRequest().getUrl());
- Assertions.assertEquals(originalUri, capturedContext.getRequest().getServiceUrl());
- Assertions.assertEquals(serviceRequestWrapper, capturedContext.getOriginRequest());
- }
-
- @Test
- void testInterceptWithFallback() throws IOException {
- // Arrange
- URI originalUri = URI.create("http://original-service/api");
- URI wrappedUri = URI.create("http://wrapped-service/api");
- HttpHeaders headers = new HttpHeaders();
-
- CallAbortedException abortedException = new CallAbortedException("test-error", null);
-
- when(serviceRequestWrapper.getURI()).thenReturn(wrappedUri);
- when(serviceRequestWrapper.getRequest()).thenReturn(request);
- when(serviceRequestWrapper.getHeaders()).thenReturn(headers);
- when(serviceRequestWrapper.getMethod()).thenReturn(HttpMethod.POST);
- when(request.getURI()).thenReturn(originalUri);
- when(pluginRunner.getLocalServiceInstance()).thenReturn(localServiceInstance);
- doThrow(abortedException)
- .when(pluginRunner)
- .run(eq(EnhancedPluginType.Client.PRE), any(EnhancedPluginContext.class));
-
- Object fallbackResponse = new MockClientHttpResponse();
- MetadataContextHolder.get().getMetadataContainer(MetadataType.APPLICATION, true).
- putMetadataObjectValue(ContextConstant.CircuitBreaker.CIRCUIT_BREAKER_FALLBACK_HTTP_RESPONSE, fallbackResponse);
-
- // Act
- interceptor.intercept(serviceRequestWrapper, "test-service", mock(LoadBalancerRequest.class));
-
- // Assert
- verify(pluginRunner).run(eq(EnhancedPluginType.Client.PRE), any(EnhancedPluginContext.class));
-
- ArgumentCaptor contextCaptor = ArgumentCaptor.forClass(EnhancedPluginContext.class);
- verify(pluginRunner).run(eq(EnhancedPluginType.Client.PRE), contextCaptor.capture());
-
- EnhancedPluginContext capturedContext = contextCaptor.getValue();
- Assertions.assertEquals(wrappedUri, capturedContext.getRequest().getUrl());
- Assertions.assertEquals(originalUri, capturedContext.getRequest().getServiceUrl());
- Assertions.assertEquals(serviceRequestWrapper, capturedContext.getOriginRequest());
- }
-
- @Test
- void testInterceptWithNoFallback() {
- // Arrange
- URI originalUri = URI.create("http://original-service/api");
- URI wrappedUri = URI.create("http://wrapped-service/api");
- HttpHeaders headers = new HttpHeaders();
-
- CallAbortedException abortedException = new CallAbortedException("test-error", null);
-
- when(serviceRequestWrapper.getURI()).thenReturn(wrappedUri);
- when(serviceRequestWrapper.getRequest()).thenReturn(request);
- when(serviceRequestWrapper.getHeaders()).thenReturn(headers);
- when(serviceRequestWrapper.getMethod()).thenReturn(HttpMethod.POST);
- when(request.getURI()).thenReturn(originalUri);
- when(pluginRunner.getLocalServiceInstance()).thenReturn(localServiceInstance);
- doThrow(abortedException)
- .when(pluginRunner)
- .run(any(), any());
- // Act
- Assertions.assertThrows(CallAbortedException.class, () -> {
- interceptor.intercept(serviceRequestWrapper, "test-service", mock(LoadBalancerRequest.class));
- });
- }
-
- @Test
- void testInterceptWithNullLocalServiceInstance() throws IOException {
- // Arrange
- URI uri = URI.create("http://test-service/api");
- when(request.getURI()).thenReturn(uri);
- when(request.getHeaders()).thenReturn(new HttpHeaders());
- when(request.getMethod()).thenReturn(HttpMethod.GET);
- when(pluginRunner.getLocalServiceInstance()).thenReturn(null);
- when(delegate.execute(any(), any())).thenReturn(response);
- when(response.getRawStatusCode()).thenReturn(200);
- when(response.getHeaders()).thenReturn(new HttpHeaders());
-
- // Act
- interceptor.intercept(request, "test-service", mock(LoadBalancerRequest.class));
-
- // Assert
- verify(pluginRunner).run(eq(EnhancedPluginType.Client.PRE), any(EnhancedPluginContext.class));
-
- ArgumentCaptor contextCaptor = ArgumentCaptor.forClass(EnhancedPluginContext.class);
- verify(pluginRunner).run(eq(EnhancedPluginType.Client.PRE), contextCaptor.capture());
-
- EnhancedPluginContext capturedContext = contextCaptor.getValue();
- assertThat(capturedContext.getLocalServiceInstance()).isNull();
- }
-
- @Test
- void testExceptionHandling() throws IOException {
- // Arrange
- LoadBalancerRequest loadBalancerRequest = mock(LoadBalancerRequest.class);
- IOException expectedException = new IOException("Test exception");
- when(delegate.execute(anyString(), any(LoadBalancerRequest.class)))
- .thenThrow(expectedException);
-
- // Act & Assert
- Exception actualException = Assertions.assertThrows(IOException.class, () -> {
- interceptor.intercept(request, "test-service", loadBalancerRequest);
- });
-
- // Verify exception handling
- verify(pluginRunner, times(1))
- .run(eq(EnhancedPluginType.Client.EXCEPTION), any(EnhancedPluginContext.class));
-
- // Verify finally block is executed
- verify(pluginRunner, times(1))
- .run(eq(EnhancedPluginType.Client.FINALLY), any(EnhancedPluginContext.class));
-
- // Verify the thrown exception is the same
- Assertions.assertEquals(expectedException, actualException);
- }
-
- static class MockClientHttpResponse implements ClientHttpResponse {
- @Override
- public HttpStatus getStatusCode() throws IOException {
- return null;
- }
-
- @Override
- public int getRawStatusCode() throws IOException {
- return 0;
- }
-
- @Override
- public String getStatusText() throws IOException {
- return null;
- }
-
- @Override
- public void close() {
-
- }
-
- @Override
- public InputStream getBody() throws IOException {
- return null;
- }
-
- @Override
- public HttpHeaders getHeaders() {
- return null;
- }
- }
-}