From 0ed97436d57ea51427384c78d484937b00ec44c8 Mon Sep 17 00:00:00 2001 From: shedfreewu Date: Mon, 11 Mar 2024 16:53:05 +0800 Subject: [PATCH] Interceptor using aspect instead of reflection --- CHANGELOG.md | 2 + .../registry/PolarisServiceRegistry.java | 2 +- .../cloud/common}/util/OkHttpUtil.java | 2 +- .../cloud/common/util/ReflectionUtils.java | 100 ----------------- .../cloud/common}/util/OkHttpUtilTest.java | 11 +- spring-cloud-tencent-coverage/pom.xml | 5 + spring-cloud-tencent-dependencies/pom.xml | 6 + .../pom.xml | 11 +- .../lossless/LosslessBeanPostProcessor.java | 95 ---------------- .../LosslessProxyServiceRegistry.java | 93 ---------------- .../lossless/LosslessRegistryAspect.java | 105 ++++++++++++++++++ .../SpringCloudLosslessActionProvider.java | 41 ++++--- .../config/LosslessAutoConfiguration.java | 17 ++- .../LosslessPropertiesAutoConfiguration.java | 3 + ...slessPropertiesBootstrapConfiguration.java | 2 + ...t.java => LosslessRegistryAspectTest.java} | 8 +- .../context/PolarisSDKContextManager.java | 2 +- .../PolarisContextAutoConfigurationTest.java | 8 ++ 18 files changed, 188 insertions(+), 325 deletions(-) rename {spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris => spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common}/util/OkHttpUtil.java (98%) rename {spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris => spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common}/util/OkHttpUtilTest.java (86%) delete mode 100644 spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/LosslessBeanPostProcessor.java delete mode 100644 spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/LosslessProxyServiceRegistry.java create mode 100644 spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/LosslessRegistryAspect.java rename spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/com/tencent/cloud/plugin/lossless/{LosslessServiceRegistryTest.java => LosslessRegistryAspectTest.java} (97%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 671ece8fb..3363c658c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2 +1,4 @@ # Change Log --- + +- [feat: support lossless register and deregister](https://github.com/Tencent/spring-cloud-tencent/issues/977) diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java index 9183f4fa0..2d12ba7fd 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java @@ -25,10 +25,10 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import com.tencent.cloud.common.metadata.StaticMetadataManager; +import com.tencent.cloud.common.util.OkHttpUtil; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; -import com.tencent.cloud.polaris.util.OkHttpUtil; import com.tencent.cloud.rpc.enhancement.stat.config.PolarisStatProperties; import com.tencent.polaris.api.config.global.StatReporterConfig; import com.tencent.polaris.api.core.ProviderAPI; diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/OkHttpUtil.java similarity index 98% rename from spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java rename to spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/OkHttpUtil.java index 69f4e9648..e34d79f56 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/util/OkHttpUtil.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/OkHttpUtil.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.util; +package com.tencent.cloud.common.util; import java.io.BufferedReader; import java.io.InputStreamReader; diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java index a21978143..b9f75b94a 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/ReflectionUtils.java @@ -18,8 +18,6 @@ package com.tencent.cloud.common.util; import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import org.springframework.util.ClassUtils; @@ -70,102 +68,4 @@ public final class ReflectionUtils extends org.springframework.util.ReflectionUt } return null; } - - /** - * get property of class object by property name. - * - * @param target object - * @param fieldName property name of class object - * @return value - */ - public static Object getObjectByFieldName(Object target, String fieldName) { - try { - Field field = target.getClass().getDeclaredField(fieldName); - field.setAccessible(true); - return field.get(target); - } - catch (Exception e) { - throw new RuntimeException("getObjectByFieldName", e); - } - } - - /** - * get property of parent class object by property name. - * - * @param target object - * @param fieldName property name of parent class object - * @return value - */ - public static Object getSuperObjectByFieldName(Object target, String fieldName) { - try { - Field field = target.getClass().getSuperclass().getDeclaredField(fieldName); - field.setAccessible(true); - return field.get(target); - } - catch (Exception e) { - throw new RuntimeException("getSuperObjectByFieldName", e); - } - } - - - /** - * set property of class object by property name. - * - * @param target object - * @param fieldName property name of class object - * @param value new value - */ - public static void setValueByFieldName(Object target, String fieldName, Object value) { - try { - Field field = target.getClass().getDeclaredField(fieldName); - setValue(target, field, value); - } - catch (Exception e) { - throw new RuntimeException("setValueByFieldName", e); - } - } - - /** - * set property of parent class object by property name. - * - * @param target object - * @param fieldName property name of parent class object - * @param value new value - */ - public static void setSuperValueByFieldName(Object target, String fieldName, Object value) { - try { - Field field = target.getClass().getSuperclass().getDeclaredField(fieldName); - setValue(target, field, value); - } - catch (Exception e) { - throw new RuntimeException("setSuperValueByFieldName", e); - } - } - - private static void setValue(Object target, Field field, Object value) { - try { - Field modifiers = getModifiersField(); - modifiers.setAccessible(true); - modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL); - field.setAccessible(true); - field.set(target, value); - } - catch (Exception e) { - throw new RuntimeException("setValue", e); - } - } - - private static Field getModifiersField() throws Exception { - Method getDeclaredFields0 = Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class); - getDeclaredFields0.setAccessible(true); - Field[] fields = (Field[]) getDeclaredFields0.invoke(Field.class, false); - Field modifierField = null; - for (Field f : fields) { - if ("modifiers".equals(f.getName())) { - modifierField = f; - break; - } - } - return modifierField; - } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/util/OkHttpUtilTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/OkHttpUtilTest.java similarity index 86% rename from spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/util/OkHttpUtilTest.java rename to spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/OkHttpUtilTest.java index 9db19b69f..2e250e3d8 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/util/OkHttpUtilTest.java +++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/util/OkHttpUtilTest.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations under the License. */ -package com.tencent.cloud.polaris.util; +package com.tencent.cloud.common.util; import org.assertj.core.util.Maps; import org.junit.jupiter.api.Test; @@ -37,7 +37,13 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Haotian Zhang */ @ExtendWith(SpringExtension.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = OkHttpUtilTest.TestApplication.class, properties = {"spring.application.name=test", "spring.cloud.polaris.discovery.register=false"}) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + classes = OkHttpUtilTest.TestApplication.class, + properties = { + "spring.application.name=test", + "spring.cloud.polaris.discovery.register=false", + "spring.cloud.gateway.enabled=false" + }) public class OkHttpUtilTest { @LocalServerPort @@ -47,6 +53,7 @@ public class OkHttpUtilTest { public void testGet() { assertThat(OkHttpUtil.get("http://localhost:" + port + "/test", Maps.newHashMap("key", "value"))).isTrue(); assertThat(OkHttpUtil.checkUrl("localhost", port, "/test", Maps.newHashMap("key", "value"))).isTrue(); + assertThat(OkHttpUtil.checkUrl("localhost", port, "test", Maps.newHashMap("key", "value"))).isTrue(); assertThat(OkHttpUtil.get("http://localhost:" + port + "/error", Maps.newHashMap("key", "value"))).isFalse(); assertThat(OkHttpUtil.get("http://localhost:55555/error", Maps.newHashMap("key", "value"))).isFalse(); } diff --git a/spring-cloud-tencent-coverage/pom.xml b/spring-cloud-tencent-coverage/pom.xml index 8a06ec039..0cb2681a4 100644 --- a/spring-cloud-tencent-coverage/pom.xml +++ b/spring-cloud-tencent-coverage/pom.xml @@ -88,6 +88,11 @@ com.tencent.cloud spring-cloud-starter-tencent-discovery-adapter-plugin + + + com.tencent.cloud + spring-cloud-tencent-lossless-plugin + diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index 89d5e7f8c..31f15fab4 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -193,6 +193,12 @@ ${revision} + + com.tencent.cloud + spring-cloud-tencent-lossless-plugin + ${revision} + + com.google.guava diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/pom.xml b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/pom.xml index bcba62f13..d02a34704 100644 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/pom.xml +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/pom.xml @@ -25,11 +25,6 @@ spring-cloud-tencent-commons - - com.tencent.cloud - spring-cloud-starter-tencent-polaris-discovery - - com.tencent.polaris lossless-register @@ -57,6 +52,12 @@ test + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-discovery + test + + com.tencent.polaris polaris-test-mock-discovery diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/LosslessBeanPostProcessor.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/LosslessBeanPostProcessor.java deleted file mode 100644 index 9a339c1df..000000000 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/LosslessBeanPostProcessor.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.plugin.lossless; - -import com.tencent.cloud.common.util.ReflectionUtils; -import com.tencent.cloud.plugin.lossless.config.LosslessProperties; -import com.tencent.cloud.polaris.context.PolarisSDKContextManager; -import com.tencent.polaris.api.pojo.BaseInstance; -import com.tencent.polaris.api.pojo.DefaultBaseInstance; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.client.serviceregistry.ServiceRegistry; - -/** - * Wrap Spring Bean and proxy for serviceRegistry. - * - * @author Shedfree Wu - */ -public class LosslessBeanPostProcessor implements BeanPostProcessor { - - private PolarisSDKContextManager polarisSDKContextManager; - - private LosslessProperties losslessProperties; - - private Registration registration; - - private Integer port; - - public LosslessBeanPostProcessor(PolarisSDKContextManager polarisSDKContextManager, - LosslessProperties losslessProperties, Registration registration, Integer port) { - this.polarisSDKContextManager = polarisSDKContextManager; - this.losslessProperties = losslessProperties; - this.registration = registration; - this.port = port; - } - - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof AbstractAutoServiceRegistration) { - wrap(bean, polarisSDKContextManager, losslessProperties, registration, port); - } - return bean; - } - - public static void wrap(Object bean, PolarisSDKContextManager polarisSDKContextManager, - LosslessProperties losslessProperties, Registration registration, Integer port) { - LosslessProxyServiceRegistry proxyServiceRegistry; - String clsName = bean.getClass().getCanonicalName(); - if (clsName.contains("org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration")) { - ServiceRegistry registry = - (ServiceRegistry) ReflectionUtils. - getObjectByFieldName(bean, "serviceRegistry"); - proxyServiceRegistry = new LosslessProxyServiceRegistry(registry, polarisSDKContextManager, registration); - ReflectionUtils.setValueByFieldName(bean, "serviceRegistry", proxyServiceRegistry); - } - else { - ServiceRegistry registry = - (ServiceRegistry) ReflectionUtils. - getSuperObjectByFieldName(bean, "serviceRegistry"); - proxyServiceRegistry = new LosslessProxyServiceRegistry(registry, polarisSDKContextManager, registration); - ReflectionUtils.setSuperValueByFieldName(bean, "serviceRegistry", proxyServiceRegistry); - } - SpringCloudLosslessActionProvider losslessActionProvider = - new SpringCloudLosslessActionProvider(proxyServiceRegistry, losslessProperties); - polarisSDKContextManager.getLosslessAPI().setLosslessActionProvider( - getBaseInstance(registration, port), losslessActionProvider); - } - - public static BaseInstance getBaseInstance(Registration registration, Integer port) { - // registration 通用,不设置 ns - DefaultBaseInstance baseInstance = new DefaultBaseInstance(); - baseInstance.setService(registration.getServiceId()); - // 由于 PolarisRegistration 的 port 在 web 启动后才能生成,需从外部传入 - baseInstance.setPort(port); - baseInstance.setHost(registration.getHost()); - return baseInstance; - } -} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/LosslessProxyServiceRegistry.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/LosslessProxyServiceRegistry.java deleted file mode 100644 index 02b00c7e8..000000000 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/LosslessProxyServiceRegistry.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.tencent.cloud.plugin.lossless; - -import java.util.concurrent.atomic.AtomicBoolean; - -import com.tencent.cloud.polaris.context.PolarisSDKContextManager; - -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.client.serviceregistry.ServiceRegistry; - -/** - * Lossless proxy for {@link ServiceRegistry}. - * - * @author Shedfree Wu - */ -public class LosslessProxyServiceRegistry implements ServiceRegistry { - - private final ServiceRegistry target; - - private Registration registration; - - private PolarisSDKContextManager polarisSDKContextManager; - - private final AtomicBoolean doneDeregister = new AtomicBoolean(false); - - public LosslessProxyServiceRegistry(ServiceRegistry target, - PolarisSDKContextManager polarisSDKContextManager, Registration registration) { - this.target = target; - this.polarisSDKContextManager = polarisSDKContextManager; - this.registration = registration; - } - - @Override - public void register(Registration registration) { - this.registration = registration; - // web started, get port from registration - polarisSDKContextManager.getLosslessAPI().losslessRegister( - LosslessBeanPostProcessor.getBaseInstance(registration, registration.getPort())); - } - - @Override - public void deregister(Registration registration) { - if (doneDeregister.compareAndSet(false, true)) { - target.deregister(registration); - } - } - - public void deregister() { - // 需要兼容其他 discovery, spring cloud deregister 统一幂等处理 - if (registration != null && doneDeregister.compareAndSet(false, true)) { - target.deregister(registration); - } - } - - public ServiceRegistry getTarget() { - return target; - } - - public Registration getRegistration() { - return registration; - } - - @Override - public void close() { - target.close(); - } - - @Override - public void setStatus(Registration registration, String status) { - target.setStatus(registration, status); - } - - @Override - public T getStatus(Registration registration) { - return target.getStatus(registration); - } -} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/LosslessRegistryAspect.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/LosslessRegistryAspect.java new file mode 100644 index 000000000..1fb6ccb2d --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/LosslessRegistryAspect.java @@ -0,0 +1,105 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.tencent.cloud.plugin.lossless; + +import java.util.concurrent.atomic.AtomicBoolean; + +import com.tencent.cloud.plugin.lossless.config.LosslessProperties; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; +import com.tencent.polaris.api.pojo.BaseInstance; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; + +import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.client.serviceregistry.ServiceRegistry; + +/** + * Intercept for of register and deregister. + * + * @author Shedfree Wu + */ +@Aspect +public class LosslessRegistryAspect { + + private ServiceRegistry serviceRegistry; + + private Registration registration; + + private LosslessProperties losslessProperties; + + private PolarisSDKContextManager polarisSDKContextManager; + + private final AtomicBoolean doneDeregister = new AtomicBoolean(false); + + + public LosslessRegistryAspect(ServiceRegistry serviceRegistry, Registration registration, + LosslessProperties losslessProperties, PolarisSDKContextManager polarisSDKContextManager) { + this.serviceRegistry = serviceRegistry; + this.registration = registration; + this.losslessProperties = losslessProperties; + this.polarisSDKContextManager = polarisSDKContextManager; + } + + @Pointcut("execution(public * org.springframework.cloud.client.serviceregistry.ServiceRegistry.register(..))") + public void registerPointcut() { + + } + + @Pointcut("execution(public * org.springframework.cloud.client.serviceregistry.ServiceRegistry.deregister(..))") + public void deregisterPointcut() { + + } + + @Around("registerPointcut()") + public Object invokeRegister(ProceedingJoinPoint joinPoint) throws Throwable { + + // web started, get port from registration + BaseInstance instance = SpringCloudLosslessActionProvider.getBaseInstance(registration); + + Runnable registerAction = () -> executeJoinPoint(joinPoint); + + SpringCloudLosslessActionProvider losslessActionProvider = + new SpringCloudLosslessActionProvider(serviceRegistry, registration, losslessProperties, registerAction); + + polarisSDKContextManager.getLosslessAPI().setLosslessActionProvider(instance, losslessActionProvider); + polarisSDKContextManager.getLosslessAPI().losslessRegister(instance); + // return void + return null; + } + + @Around("deregisterPointcut()") + public Object invokeDeregister(ProceedingJoinPoint joinPoint) throws Throwable { + if (doneDeregister.compareAndSet(false, true)) { + return joinPoint.proceed(); + } + else { + return null; + } + } + + public void executeJoinPoint(ProceedingJoinPoint joinPoint) { + try { + joinPoint.proceed(); + } + catch (Throwable e) { + throw new RuntimeException(e); + } + } +} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/SpringCloudLosslessActionProvider.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/SpringCloudLosslessActionProvider.java index 05fc3b5d2..05cd23f6d 100644 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/SpringCloudLosslessActionProvider.java +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/SpringCloudLosslessActionProvider.java @@ -19,15 +19,17 @@ package com.tencent.cloud.plugin.lossless; import java.util.HashMap; import java.util.Map; -import java.util.function.Consumer; +import com.tencent.cloud.common.util.OkHttpUtil; import com.tencent.cloud.plugin.lossless.config.LosslessProperties; -import com.tencent.cloud.polaris.util.OkHttpUtil; import com.tencent.polaris.api.plugin.lossless.InstanceProperties; import com.tencent.polaris.api.plugin.lossless.LosslessActionProvider; +import com.tencent.polaris.api.pojo.BaseInstance; +import com.tencent.polaris.api.pojo.DefaultBaseInstance; import com.tencent.polaris.api.utils.StringUtils; import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import org.springframework.http.HttpHeaders; /** @@ -36,22 +38,20 @@ import org.springframework.http.HttpHeaders; * @author Shedfree Wu */ public class SpringCloudLosslessActionProvider implements LosslessActionProvider { - - private LosslessProxyServiceRegistry losslessProxyServiceRegistry; + private ServiceRegistry serviceRegistry; private LosslessProperties losslessProperties; - private Consumer registrationConsumer; + private Runnable originalRegisterAction; private Registration registration; - public SpringCloudLosslessActionProvider( - LosslessProxyServiceRegistry losslessProxyServiceRegistry, - LosslessProperties losslessProperties) { - this.losslessProxyServiceRegistry = losslessProxyServiceRegistry; + public SpringCloudLosslessActionProvider(ServiceRegistry serviceRegistry, Registration registration, + LosslessProperties losslessProperties, Runnable originalRegisterAction) { + this.serviceRegistry = serviceRegistry; + this.registration = registration; this.losslessProperties = losslessProperties; - this.registrationConsumer = losslessProxyServiceRegistry.getTarget()::register; - this.registration = losslessProxyServiceRegistry.getRegistration(); + this.originalRegisterAction = originalRegisterAction; } @Override @@ -61,12 +61,13 @@ public class SpringCloudLosslessActionProvider implements LosslessActionProvider @Override public void doRegister(InstanceProperties instanceProperties) { - registrationConsumer.accept(registration); + // use lambda to do original register + originalRegisterAction.run(); } @Override public void doDeregister() { - losslessProxyServiceRegistry.deregister(); + serviceRegistry.deregister(registration); } /** @@ -86,4 +87,18 @@ public class SpringCloudLosslessActionProvider implements LosslessActionProvider return OkHttpUtil.checkUrl("localhost", registration.getPort(), losslessProperties.getHealthCheckPath(), headers); } + + public static BaseInstance getBaseInstance(Registration registration) { + return getBaseInstance(registration, registration.getPort()); + } + + public static BaseInstance getBaseInstance(Registration registration, Integer port) { + // for common spring cloud registration, not set namespace + DefaultBaseInstance baseInstance = new DefaultBaseInstance(); + baseInstance.setService(registration.getServiceId()); + // before web start, port in registration not init + baseInstance.setPort(port); + baseInstance.setHost(registration.getHost()); + return baseInstance; + } } diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessAutoConfiguration.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessAutoConfiguration.java index 22c9c73d2..7bcc5df85 100644 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessAutoConfiguration.java +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessAutoConfiguration.java @@ -18,12 +18,13 @@ package com.tencent.cloud.plugin.lossless.config; -import com.tencent.cloud.plugin.lossless.LosslessBeanPostProcessor; +import com.tencent.cloud.plugin.lossless.LosslessRegistryAspect; +import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; import com.tencent.cloud.polaris.context.PolarisSDKContextManager; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -34,18 +35,14 @@ import org.springframework.context.annotation.Import; * @author Shedfree Wu */ @Configuration(proxyBeanMethods = false) +@ConditionalOnPolarisEnabled @Import(LosslessPropertiesAutoConfiguration.class) public class LosslessAutoConfiguration { - @Value("${server.port:8080}") - private Integer port; - @Bean @ConditionalOnMissingBean - public LosslessBeanPostProcessor losslessBeanPostProcessor(Registration registration, - PolarisSDKContextManager polarisSDKContextManager, - LosslessProperties losslessProperties) { - return new LosslessBeanPostProcessor(polarisSDKContextManager, losslessProperties, - registration, port); + public LosslessRegistryAspect losslessRegistryAspect(ServiceRegistry serviceRegistry, Registration registration, + LosslessProperties losslessProperties, PolarisSDKContextManager polarisSDKContextManager) { + return new LosslessRegistryAspect(serviceRegistry, registration, losslessProperties, polarisSDKContextManager); } } diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessPropertiesAutoConfiguration.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessPropertiesAutoConfiguration.java index f320f246f..5d104704f 100644 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessPropertiesAutoConfiguration.java +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessPropertiesAutoConfiguration.java @@ -18,6 +18,8 @@ package com.tencent.cloud.plugin.lossless.config; +import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; + import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -29,6 +31,7 @@ import org.springframework.context.annotation.Configuration; * @author Shedfree Wu */ @Configuration(proxyBeanMethods = false) +@ConditionalOnPolarisEnabled @EnableConfigurationProperties(LosslessProperties.class) public class LosslessPropertiesAutoConfiguration { diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessPropertiesBootstrapConfiguration.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessPropertiesBootstrapConfiguration.java index 861057d61..dd047cabc 100644 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessPropertiesBootstrapConfiguration.java +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/main/java/com/tencent/cloud/plugin/lossless/config/LosslessPropertiesBootstrapConfiguration.java @@ -17,6 +17,7 @@ package com.tencent.cloud.plugin.lossless.config; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -27,6 +28,7 @@ import org.springframework.context.annotation.Import; * @author Shedfree Wu */ @Configuration(proxyBeanMethods = false) +@ConditionalOnProperty("spring.cloud.polaris.enabled") @Import(LosslessPropertiesAutoConfiguration.class) public class LosslessPropertiesBootstrapConfiguration { diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/com/tencent/cloud/plugin/lossless/LosslessServiceRegistryTest.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/com/tencent/cloud/plugin/lossless/LosslessRegistryAspectTest.java similarity index 97% rename from spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/com/tencent/cloud/plugin/lossless/LosslessServiceRegistryTest.java rename to spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/com/tencent/cloud/plugin/lossless/LosslessRegistryAspectTest.java index d0cf9bd4c..6a1255391 100644 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/com/tencent/cloud/plugin/lossless/LosslessServiceRegistryTest.java +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/com/tencent/cloud/plugin/lossless/LosslessRegistryAspectTest.java @@ -19,6 +19,7 @@ package com.tencent.cloud.plugin.lossless; import java.util.Collections; +import com.tencent.cloud.common.util.OkHttpUtil; import com.tencent.cloud.plugin.lossless.config.LosslessAutoConfiguration; import com.tencent.cloud.plugin.lossless.config.LosslessPropertiesBootstrapConfiguration; import com.tencent.cloud.polaris.context.PolarisSDKContextManager; @@ -27,7 +28,6 @@ import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryClientConfiguration; import com.tencent.cloud.polaris.registry.PolarisRegistration; import com.tencent.cloud.polaris.registry.PolarisServiceRegistry; -import com.tencent.cloud.polaris.util.OkHttpUtil; import com.tencent.polaris.api.pojo.ServiceKey; import com.tencent.polaris.test.mock.discovery.NamingServer; import org.junit.jupiter.api.AfterAll; @@ -46,11 +46,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; /** - * Test for {@link LosslessProxyServiceRegistry}. + * Test for {@link LosslessRegistryAspect}. * * @author Shedfree Wu */ -public class LosslessServiceRegistryTest { +public class LosslessRegistryAspectTest { private static String NAMESPACE_TEST = "Test"; @@ -60,7 +60,7 @@ public class LosslessServiceRegistryTest { private static int APPLICATION_PORT = 19091; - private static int LOSSLESS_PORT_1 = 28081; + private static int LOSSLESS_PORT_1 = 28083; private static NamingServer namingServer; diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisSDKContextManager.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisSDKContextManager.java index f7ff388ab..143b6fbb7 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisSDKContextManager.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/PolarisSDKContextManager.java @@ -83,7 +83,7 @@ public class PolarisSDKContextManager { providerAPI = null; } - // destroy ProviderAPI + // destroy LosslessAPI if (Objects.nonNull(losslessAPI)) { ((AutoCloseable) losslessAPI).close(); losslessAPI = null; diff --git a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfigurationTest.java b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfigurationTest.java index e5d05b6a3..e176b723d 100644 --- a/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfigurationTest.java +++ b/spring-cloud-tencent-polaris-context/src/test/java/com/tencent/cloud/polaris/context/config/PolarisContextAutoConfigurationTest.java @@ -46,4 +46,12 @@ public class PolarisContextAutoConfigurationTest { assertThat(polarisSDKContextManager).isNotNull(); }); } + + @Test + public void testLosslessAPIProperties() { + contextRunner.run(context -> { + PolarisSDKContextManager polarisSDKContextManager = context.getBean(PolarisSDKContextManager.class); + assertThat(polarisSDKContextManager.getLosslessAPI()).isNotNull(); + }); + } }