diff --git a/CHANGELOG.md b/CHANGELOG.md index 0890e83db..332f9f58c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,17 @@ - [Optimize:optimize SpringValueProcessor.](https://github.com/Tencent/spring-cloud-tencent/pull/655) - [Optimize/optimize annotation.](https://github.com/Tencent/spring-cloud-tencent/pull/672) +- [enhancement: revert default value when the field is deleted in @ConfigurationProperties bean](https://github.com/Tencent/spring-cloud-tencent/issues/681) - [Optimize: Register the service with the ProviderAPI#registerInstance method.](https://github.com/Tencent/spring-cloud-tencent/pull/686) - [docs:update PR template.](https://github.com/Tencent/spring-cloud-tencent/pull/690) +- [Feature:support multi register and discovery both to nacos and polaris.](https://github.com/Tencent/spring-cloud-tencent/pull/693) - [Optimize: update spring-cloud-starter-tencent-all pom to jar](https://github.com/Tencent/spring-cloud-tencent/pull/694) - [Optimize: remote deprecated method](https://github.com/Tencent/spring-cloud-tencent/pull/697) - [Test:support environment variable metadata test](https://github.com/Tencent/spring-cloud-tencent/pull/698) - [Code optimize & add junit tests.](https://github.com/Tencent/spring-cloud-tencent/pull/701) -- [Test: remote deprecated method in test](https://github.com/Tencent/spring-cloud-tencent/pull/706) \ No newline at end of file +- [Test: remote deprecated method in test](https://github.com/Tencent/spring-cloud-tencent/pull/706) +- [upgrade protobuf-java.version to 3.21.7](https://github.com/Tencent/spring-cloud-tencent/pull/715) +- [docs:update README.](https://github.com/Tencent/spring-cloud-tencent/pull/718) +- [Fix:fix javadoc.](https://github.com/Tencent/spring-cloud-tencent/pull/721) +- [Code optimization & correct comment](https://github.com/Tencent/spring-cloud-tencent/pull/722) +- [fix:fix discovery junit.](https://github.com/Tencent/spring-cloud-tencent/pull/725) diff --git a/README-zh.md b/README-zh.md index 309365a7e..06875b20a 100644 --- a/README-zh.md +++ b/README-zh.md @@ -7,7 +7,6 @@ [![Build Status](https://github.com/Tencent/spring-cloud-tencent/actions/workflows/junit_test.yml/badge.svg)](https://github.com/Tencent/spring-cloud-tencent/actions/workflows/junit_test.yml) [![codecov.io](https://codecov.io/gh/Tencent/spring-cloud-tencent/branch/2021.0/graph/badge.svg)](https://codecov.io/gh/Tencent/spring-cloud-tencent?branch=2021.0) -[![Language grade: Java](https://img.shields.io/lgtm/grade/java/g/Tencent/spring-cloud-tencent.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Tencent/spring-cloud-tencent/context:java) [English](./README.md) | 简体中文 @@ -108,23 +107,26 @@ You can build this project with command: ## 文档 - 使用文档 - - [Spring Cloud Tencent Version Management](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86) - - [Spring Cloud Tencent Discovery](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Discovery-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - - [Spring Cloud Tencent Config](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Config-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - - [Spring Cloud Tencent Rate Limit](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Rate-Limit-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - - [Spring Cloud Tencent CircuitBreaker](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Circuitbreaker-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - - [Spring Cloud Tencent Router](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Router-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - - [Spring Cloud Starter Tencent RPC Enhancement](https://github.com/Tencent/spring-cloud-tencent/wiki/RPC%E5%A2%9E%E5%BC%BA) - - [Spring Cloud Tencent Metadata Transfer](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Metadata-Transfer-%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97) - - [Actuator Endpoint Extension](https://github.com/Tencent/spring-cloud-tencent/wiki/Actuator-Endpoint-%E6%89%A9%E5%B1%95) + - [Spring Cloud Tencent 版本管理](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86) + - [服务注册与发现](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Discovery-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) + - [配置中心](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Config-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) + - [服务限流](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Rate-Limit-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) + - [服务熔断](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Circuitbreaker-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) + - [服务路由](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Router-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) + - [RPC增强](https://github.com/Tencent/spring-cloud-tencent/wiki/RPC%E5%A2%9E%E5%BC%BA) + - [元数据传递](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Metadata-Transfer-%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97) + - [场景化插件](https://github.com/Tencent/spring-cloud-tencent/wiki/场景化插件) + - [Actuator Endpoint 扩展](https://github.com/Tencent/spring-cloud-tencent/wiki/Actuator-Endpoint-%E6%89%A9%E5%B1%95) - 最佳实践 - - [Multi-feature environment](https://github.com/Tencent/spring-cloud-tencent/wiki/%E5%A4%9A%E7%89%B9%E6%80%A7%E7%8E%AF%E5%A2%83) - - [Multi-registration and multi-discovery](https://github.com/Tencent/spring-cloud-tencent/wiki/Multi-registration-and-multi-discovery) + - [可观测性实践](https://github.com/Tencent/spring-cloud-tencent/wiki/可观测性实践) + - [测试环境路由](https://github.com/Tencent/spring-cloud-tencent/wiki/%E6%B5%8B%E8%AF%95%E7%8E%AF%E5%A2%83%E8%B7%AF%E7%94%B1) + - [Spring Cloud Gateway 流量染色](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Gateway-%E6%B5%81%E9%87%8F%E6%9F%93%E8%89%B2) + - [多注册与多发现](https://github.com/Tencent/spring-cloud-tencent/wiki/Multi-registration-and-multi-discovery) - 开发文档 - - [Project Structure Overview](https://github.com/Tencent/spring-cloud-tencent/wiki/%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%A7%88) - - [Participate in co-construction](https://github.com/Tencent/spring-cloud-tencent/wiki/%E5%8F%82%E4%B8%8E%E5%85%B1%E5%BB%BA) + - [项目概览](https://github.com/Tencent/spring-cloud-tencent/wiki/%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%A7%88) + - [参与共建](https://github.com/Tencent/spring-cloud-tencent/wiki/%E5%8F%82%E4%B8%8E%E5%85%B1%E5%BB%BA) ## 交流群 diff --git a/README.md b/README.md index beb5abde4..d54558221 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ [![Build Status](https://github.com/Tencent/spring-cloud-tencent/actions/workflows/junit_test.yml/badge.svg)](https://github.com/Tencent/spring-cloud-tencent/actions/workflows/junit_test.yml) [![codecov.io](https://codecov.io/gh/Tencent/spring-cloud-tencent/branch/2021.0/graph/badge.svg)](https://codecov.io/gh/Tencent/spring-cloud-tencent?branch=2021.0) -[![Language grade: Java](https://img.shields.io/lgtm/grade/java/g/Tencent/spring-cloud-tencent.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Tencent/spring-cloud-tencent/context:java) English | [简体中文](./README-zh.md) @@ -115,10 +114,13 @@ You can build this project with command: - [Spring Cloud Tencent Router](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Router-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3) - [Spring Cloud Starter Tencent RPC Enhancement](https://github.com/Tencent/spring-cloud-tencent/wiki/RPC%E5%A2%9E%E5%BC%BA) - [Spring Cloud Tencent Metadata Transfer](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Tencent-Metadata-Transfer-%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97) + - [Spring Cloud Tencent Plugins](https://github.com/Tencent/spring-cloud-tencent/wiki/%E5%9C%BA%E6%99%AF%E5%8C%96%E6%8F%92%E4%BB%B6) - [Actuator Endpoint Extension](https://github.com/Tencent/spring-cloud-tencent/wiki/Actuator-Endpoint-%E6%89%A9%E5%B1%95) - Best Practices + - [Observability Practice](https://github.com/Tencent/spring-cloud-tencent/wiki/%E5%8F%AF%E8%A7%82%E6%B5%8B%E6%80%A7%E5%AE%9E%E8%B7%B5) - [Multi-feature environment](https://github.com/Tencent/spring-cloud-tencent/wiki/%E5%A4%9A%E7%89%B9%E6%80%A7%E7%8E%AF%E5%A2%83) + - [Spring Cloud Gateway Traffic Staining](https://github.com/Tencent/spring-cloud-tencent/wiki/Spring-Cloud-Gateway-%E6%B5%81%E9%87%8F%E6%9F%93%E8%89%B2) - [Multi-registration and multi-discovery](https://github.com/Tencent/spring-cloud-tencent/wiki/Multi-registration-and-multi-discovery) - Development documentation 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 3736a45d3..a245d695a 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 @@ -59,7 +59,7 @@ public class PolarisCircuitBreakerAutoConfiguration { // Turn on circuitbreaker configuration configuration.getConsumer().getCircuitBreaker().setEnable(true); - // Set excludeCircuitBreakInstances to false + // Set excludeCircuitBreakInstances to true RecoverRouterConfig recoverRouterConfig = configuration.getConsumer().getServiceRouter() .getPluginConfig(ServiceRouterConfig.DEFAULT_ROUTER_RECOVER, RecoverRouterConfig.class); diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/AffectedConfigurationPropertiesRebinder.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/AffectedConfigurationPropertiesRebinder.java index c18c7f29e..711df1483 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/AffectedConfigurationPropertiesRebinder.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/AffectedConfigurationPropertiesRebinder.java @@ -18,10 +18,18 @@ package com.tencent.cloud.polaris.config.adapter; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import com.tencent.cloud.common.util.ReflectionUtils; +import com.tencent.polaris.api.utils.MapUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.boot.context.properties.ConfigurationPropertiesBean; @@ -31,6 +39,7 @@ import org.springframework.cloud.context.properties.ConfigurationPropertiesRebin import org.springframework.context.ApplicationContext; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; /** * Optimize {@link ConfigurationPropertiesRebinder}, only rebuild affected beans. @@ -39,9 +48,13 @@ import org.springframework.util.CollectionUtils; */ public class AffectedConfigurationPropertiesRebinder extends ConfigurationPropertiesRebinder { + private static final Logger LOGGER = LoggerFactory.getLogger(AffectedConfigurationPropertiesRebinder.class); + private ApplicationContext applicationContext; private Map propertiesBeans = new HashMap<>(); + private final Map> propertiesBeanDefaultValues = new ConcurrentHashMap<>(); + public AffectedConfigurationPropertiesRebinder(ConfigurationPropertiesBeans beans) { super(beans); } @@ -53,6 +66,7 @@ public class AffectedConfigurationPropertiesRebinder extends ConfigurationProper this.applicationContext = applicationContext; propertiesBeans = ConfigurationPropertiesBean.getAll(applicationContext); + initPropertiesBeanDefaultValues(propertiesBeans); } @Override @@ -75,8 +89,62 @@ public class AffectedConfigurationPropertiesRebinder extends ConfigurationProper .toString(); if (key.startsWith(propertiesPrefix)) { rebind(name); + rebindDefaultValue(name, key); } }); }); } + + private void rebindDefaultValue(String beanName, String key) { + String changeValue = applicationContext.getEnvironment().getProperty(key); + if (StringUtils.hasLength(changeValue)) { + return; + } + + Map defaultValues = propertiesBeanDefaultValues.get(beanName); + if (MapUtils.isEmpty(defaultValues)) { + return; + } + try { + String fieldName = key.substring(key.lastIndexOf(".") + 1); + + Object bean = applicationContext.getBean(beanName); + Field field = ReflectionUtils.findField(bean.getClass(), fieldName); + if (field != null) { + field.setAccessible(true); + field.set(bean, defaultValues.get(fieldName)); + } + } + catch (Exception e) { + LOGGER.error("[SCT Config] rebind default value error, bean = {}, key = {}", beanName, key); + } + } + + private void initPropertiesBeanDefaultValues(Map propertiesBeans) { + if (MapUtils.isEmpty(propertiesBeans)) { + return; + } + + for (ConfigurationPropertiesBean propertiesBean : propertiesBeans.values()) { + Map defaultValues = new HashMap<>(); + try { + Object instance = propertiesBean.getInstance().getClass().getDeclaredConstructor((Class[]) null).newInstance(); + ReflectionUtils.doWithFields(instance.getClass(), field -> { + try { + field.setAccessible(true); + defaultValues.put(field.getName(), field.get(instance)); + } + catch (Exception ignored) { + } + }, field -> { + int modifiers = field.getModifiers(); + return !Modifier.isFinal(modifiers) && !Modifier.isStatic(modifiers) && ReflectionUtils.writableBeanField(field); + }); + } + catch (Exception ignored) { + } + + propertiesBeanDefaultValues.put(propertiesBean.getName(), defaultValues); + } + } } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFilePuller.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFilePuller.java index 2399ab2f8..fc203029b 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFilePuller.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFilePuller.java @@ -81,6 +81,7 @@ public final class PolarisConfigFilePuller { * * @param compositePropertySource compositePropertySource * @param activeProfiles activeProfiles + * @param defaultProfiles defaultProfiles * @param serviceName serviceName */ public void initInternalConfigFiles(CompositePropertySource compositePropertySource, String[] activeProfiles, diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/configdata/PolarisConfigDataLoader.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/configdata/PolarisConfigDataLoader.java index 300ea1bb3..613f03603 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/configdata/PolarisConfigDataLoader.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/configdata/PolarisConfigDataLoader.java @@ -52,7 +52,6 @@ import static org.springframework.boot.context.config.ConfigData.Option.PROFILE_ * Load {@link ConfigData} via {@link PolarisConfigDataLoader} * * @author wlx - * @date 2022/7/5 11:14 PM */ public class PolarisConfigDataLoader implements ConfigDataLoader { diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/configdata/PolarisConfigDataResource.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/configdata/PolarisConfigDataResource.java index c0a33566b..ee76e9f18 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/configdata/PolarisConfigDataResource.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/configdata/PolarisConfigDataResource.java @@ -30,7 +30,6 @@ import org.springframework.boot.context.config.Profiles; * A polaris configData resource from which {@link ConfigData} can be loaded. * * @author wlx - * @date 2022/7/5 11:13 PM */ public class PolarisConfigDataResource extends ConfigDataResource { diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/property/PlaceholderHelper.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/property/PlaceholderHelper.java index 8827fa3ed..9f8e9b76e 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/property/PlaceholderHelper.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/property/PlaceholderHelper.java @@ -52,7 +52,7 @@ public class PlaceholderHelper { * @param beanFactory beanFactory * @param beanName beanName * @param placeholder placeholder - * @return "${somePropertyValue}" -> "the actual property value" + * @return "${somePropertyValue}" -> "the actual property value" */ public Object resolvePropertyValue(ConfigurableBeanFactory beanFactory, String beanName, String placeholder) { // resolve string value @@ -77,16 +77,16 @@ public class PlaceholderHelper { } /** - * * @param propertyString propertyString - * @return - * Extract keys from placeholder, e.g. - *
  • ${some.key} => "some.key"
  • - *
  • ${some.key:${some.other.key:100}} => "some.key", "some.other.key"
  • - *
  • ${${some.key}} => "some.key"
  • - *
  • ${${some.key:other.key}} => "some.key"
  • - *
  • ${${some.key}:${another.key}} => "some.key", "another.key"
  • - *
  • #{new java.text.SimpleDateFormat('${some.key}').parse('${another.key}')} => "some.key", "another.key"
  • + * @return Extract keys from placeholder, e.g. + *
      + *
    • ${some.key} => "some.key"
    • + *
    • ${some.key:${some.other.key:100}} => "some.key", "some.other.key"
    • + *
    • ${${some.key}} => "some.key"
    • + *
    • ${${some.key:other.key}} => "some.key"
    • + *
    • ${${some.key}:${another.key}} => "some.key", "another.key"
    • + *
    • #{new java.text.SimpleDateFormat('${some.key}').parse('${another.key}')} => "some.key", "another.key"
    • + *
    */ public Set extractPlaceholderKeys(String propertyString) { Set placeholderKeys = Sets.newHashSet(); diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/property/SpringValueRegistry.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/property/SpringValueRegistry.java index 473ed909e..9e2c2657d 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/property/SpringValueRegistry.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/spring/property/SpringValueRegistry.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -33,6 +34,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.DisposableBean; /** * Spring value auto registry. @@ -43,13 +45,14 @@ import org.springframework.beans.factory.BeanFactory; * * @author weihubeats 2022-7-10 */ -public class SpringValueRegistry { +public class SpringValueRegistry implements DisposableBean { private static final Logger logger = LoggerFactory.getLogger(SpringValueRegistry.class); private static final long CLEAN_INTERVAL_IN_SECONDS = 5; private final Map> registry = Maps.newConcurrentMap(); private final AtomicBoolean initialized = new AtomicBoolean(false); private final Object LOCK = new Object(); + private ScheduledExecutorService executor; public void register(BeanFactory beanFactory, String key, SpringValue springValue) { if (!registry.containsKey(beanFactory)) { @@ -77,8 +80,9 @@ public class SpringValueRegistry { } private void initialize() { - Executors.newSingleThreadScheduledExecutor( - new NamedThreadFactory("polaris-spring-value-registry")).scheduleAtFixedRate( + executor = Executors.newSingleThreadScheduledExecutor( + new NamedThreadFactory("polaris-spring-value-registry")); + executor.scheduleAtFixedRate( () -> { try { scanAndClean(); @@ -97,4 +101,9 @@ public class SpringValueRegistry { springValues.entries().removeIf(springValue -> !springValue.getValue().isTargetBeanValid()); } } + + @Override + public void destroy() throws Exception { + executor.shutdown(); + } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java index c98f64dfb..409184782 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/DiscoveryPropertiesAutoConfiguration.java @@ -21,6 +21,8 @@ import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; import com.tencent.cloud.polaris.extend.consul.ConsulConfigModifier; import com.tencent.cloud.polaris.extend.consul.ConsulContextProperties; +import com.tencent.cloud.polaris.extend.nacos.NacosConfigModifier; +import com.tencent.cloud.polaris.extend.nacos.NacosContextProperties; import com.tencent.polaris.api.core.ConsumerAPI; import com.tencent.polaris.api.core.ProviderAPI; import com.tencent.polaris.client.api.SDKContext; @@ -38,7 +40,7 @@ import org.springframework.context.annotation.Import; */ @Configuration(proxyBeanMethods = false) @ConditionalOnPolarisEnabled -@Import({PolarisDiscoveryProperties.class, ConsulContextProperties.class}) +@Import({PolarisDiscoveryProperties.class, ConsulContextProperties.class, NacosContextProperties.class}) public class DiscoveryPropertiesAutoConfiguration { @Bean @@ -66,4 +68,10 @@ public class DiscoveryPropertiesAutoConfiguration { public PolarisDiscoveryConfigModifier polarisDiscoveryConfigModifier(PolarisDiscoveryProperties polarisDiscoveryProperties) { return new PolarisDiscoveryConfigModifier(polarisDiscoveryProperties); } + + @Bean + @ConditionalOnMissingBean + public NacosConfigModifier nacosConfigModifier(@Autowired(required = false) NacosContextProperties nacosContextProperties) { + return new NacosConfigModifier(nacosContextProperties); + } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosConfigModifier.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosConfigModifier.java new file mode 100644 index 000000000..6f8cbf78d --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosConfigModifier.java @@ -0,0 +1,114 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.extend.nacos; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Map; +import java.util.Objects; + +import com.tencent.cloud.common.constant.ContextConstant; +import com.tencent.cloud.polaris.context.PolarisConfigModifier; +import com.tencent.polaris.api.config.plugin.DefaultPlugins; +import com.tencent.polaris.factory.config.ConfigurationImpl; +import com.tencent.polaris.factory.config.consumer.DiscoveryConfigImpl; +import com.tencent.polaris.factory.config.global.ServerConnectorConfigImpl; +import com.tencent.polaris.factory.config.provider.RegisterConfigImpl; +import org.apache.commons.lang.StringUtils; + +import org.springframework.util.CollectionUtils; + +/** + * {@link PolarisConfigModifier} impl of Nacos. + * + * @author lingxiao.wlx + */ +public class NacosConfigModifier implements PolarisConfigModifier { + private static final String ID = "nacos"; + /** + * nacos username. + */ + public static final String USERNAME = "username"; + /** + * nacos password. + */ + public static final String PASSWORD = "password"; + /** + * nacos contextPath. + */ + public static final String CONTEXT_PATH = "contextPath"; + + private final NacosContextProperties nacosContextProperties; + + public NacosConfigModifier(NacosContextProperties nacosContextProperties) { + this.nacosContextProperties = nacosContextProperties; + } + + @Override + public void modify(ConfigurationImpl configuration) { + if (Objects.isNull(nacosContextProperties) || !nacosContextProperties.isEnabled()) { + return; + } + if (CollectionUtils.isEmpty(configuration.getGlobal().getServerConnectors())) { + configuration.getGlobal().setServerConnectors(new ArrayList<>()); + } + if (CollectionUtils.isEmpty(configuration.getGlobal().getServerConnectors()) + && null != configuration.getGlobal().getServerConnector()) { + configuration.getGlobal().getServerConnectors().add(configuration.getGlobal().getServerConnector()); + } + ServerConnectorConfigImpl serverConnectorConfig = new ServerConnectorConfigImpl(); + serverConnectorConfig.setId(ID); + if (StringUtils.isBlank(nacosContextProperties.getServerAddr())) { + throw new IllegalArgumentException("nacos server addr must not be empty, please set it by" + + "spring.cloud.nacos.discovery.server-addr"); + } + serverConnectorConfig.setAddresses( + Collections.singletonList(nacosContextProperties.getServerAddr())); + serverConnectorConfig.setProtocol(DefaultPlugins.SERVER_CONNECTOR_NACOS); + + Map metadata = serverConnectorConfig.getMetadata(); + if (StringUtils.isNotBlank(nacosContextProperties.getUsername())) { + metadata.put(USERNAME, nacosContextProperties.getUsername()); + } + + if (StringUtils.isNotBlank(nacosContextProperties.getPassword())) { + metadata.put(PASSWORD, nacosContextProperties.getPassword()); + } + + if (StringUtils.isNotBlank(nacosContextProperties.getContextPath())) { + metadata.put(CONTEXT_PATH, nacosContextProperties.getContextPath()); + } + + configuration.getGlobal().getServerConnectors().add(serverConnectorConfig); + DiscoveryConfigImpl discoveryConfig = new DiscoveryConfigImpl(); + discoveryConfig.setServerConnectorId(ID); + discoveryConfig.setEnable(nacosContextProperties.isDiscoveryEnabled()); + configuration.getConsumer().getDiscoveries().add(discoveryConfig); + + RegisterConfigImpl registerConfig = new RegisterConfigImpl(); + registerConfig.setServerConnectorId(ID); + registerConfig.setEnable(nacosContextProperties.isRegisterEnabled()); + configuration.getProvider().getRegisters().add(registerConfig); + } + + @Override + public int getOrder() { + return ContextConstant.ModifierOrder.LAST; + } +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosContextProperties.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosContextProperties.java new file mode 100644 index 000000000..905b3818d --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/extend/nacos/NacosContextProperties.java @@ -0,0 +1,172 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.extend.nacos; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Discovery configuration of Nacos. + * + * @author lingxiao.wlx + */ +@ConfigurationProperties("spring.cloud.nacos") +public class NacosContextProperties { + + /** + * Nacos default group name. + */ + public static final String DEFAULT_GROUP = "DEFAULT_GROUP"; + + /** + * Nacos default cluster name. + */ + public static final String DEFAULT_CLUSTER = "DEFAULT"; + + private boolean enabled = false; + + @Value("${spring.cloud.nacos.discovery.enabled:#{'true'}}") + private boolean discoveryEnabled; + + /** + * if you just want to subscribe on nacos , but don't want to register your service, set it to + * false. + */ + @Value("${spring.cloud.nacos.discovery.register-enabled:#{'true'}}") + private boolean registerEnabled; + + /** + * nacos discovery server address. + */ + @Value("${spring.cloud.nacos.discovery.server-addr:}") + private String serverAddr; + + /** + * the nacos authentication username. + */ + @Value("${spring.cloud.nacos.discovery.username:}") + private String username; + + /** + * the nacos authentication password. + */ + @Value("${spring.cloud.nacos.discovery.password:}") + private String password; + + /** + * cluster name for nacos . + */ + @Value("${spring.cloud.nacos.discovery.cluster-name:DEFAULT}") + private String clusterName = DEFAULT_CLUSTER; + + /** + * group name for nacos. + */ + @Value("${spring.cloud.nacos.discovery.group:DEFAULT_GROUP}") + private String group = DEFAULT_GROUP; + + private String contextPath; + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isRegisterEnabled() { + return registerEnabled; + } + + public void setRegisterEnabled(boolean registerEnabled) { + this.registerEnabled = registerEnabled; + } + + public boolean isDiscoveryEnabled() { + return discoveryEnabled; + } + + public void setDiscoveryEnabled(boolean discoveryEnabled) { + this.discoveryEnabled = discoveryEnabled; + } + + public String getServerAddr() { + return serverAddr; + } + + public void setServerAddr(String serverAddr) { + this.serverAddr = serverAddr; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getClusterName() { + return clusterName; + } + + public void setClusterName(String clusterName) { + this.clusterName = clusterName; + } + + public String getGroup() { + return group; + } + + public void setGroup(String group) { + this.group = group; + } + + public String getContextPath() { + return contextPath; + } + + public void setContextPath(String contextPath) { + this.contextPath = contextPath; + } + + @Override + public String toString() { + return "NacosContextProperties{" + + "enabled=" + enabled + + ", discoveryEnabled=" + discoveryEnabled + + ", registerEnabled=" + registerEnabled + + ", serverAddr='" + serverAddr + '\'' + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + ", clusterName='" + clusterName + '\'' + + ", group='" + group + '\'' + + ", contextPath='" + contextPath + '\'' + + '}'; + } +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java index 7ff1c2e39..22f7a66bb 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java @@ -21,10 +21,12 @@ package com.tencent.cloud.polaris.registry; import java.net.URI; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; import com.tencent.cloud.polaris.extend.consul.ConsulContextProperties; +import com.tencent.cloud.polaris.extend.nacos.NacosContextProperties; import com.tencent.polaris.client.api.SDKContext; import org.apache.commons.lang.StringUtils; @@ -33,6 +35,9 @@ import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; +import static com.tencent.cloud.polaris.extend.nacos.NacosContextProperties.DEFAULT_CLUSTER; +import static com.tencent.cloud.polaris.extend.nacos.NacosContextProperties.DEFAULT_GROUP; + /** * Registration object of Polaris. * @@ -42,6 +47,8 @@ public class PolarisRegistration implements Registration { private static final String METADATA_KEY_IP = "internal-ip"; private static final String METADATA_KEY_ADDRESS = "internal-address"; + private static final String GROUP_SERVER_ID_FORMAT = "%s__%s"; + private static final String NACOS_CLUSTER = "nacos.cluster"; private final PolarisDiscoveryProperties polarisDiscoveryProperties; @@ -51,6 +58,8 @@ public class PolarisRegistration implements Registration { private final StaticMetadataManager staticMetadataManager; + private final NacosContextProperties nacosContextProperties; + private Map metadata; private String host; @@ -60,18 +69,30 @@ public class PolarisRegistration implements Registration { public PolarisRegistration( PolarisDiscoveryProperties polarisDiscoveryProperties, @Nullable ConsulContextProperties consulContextProperties, - SDKContext context, StaticMetadataManager staticMetadataManager) { + SDKContext context, StaticMetadataManager staticMetadataManager, + @Nullable NacosContextProperties nacosContextProperties) { this.polarisDiscoveryProperties = polarisDiscoveryProperties; this.consulContextProperties = consulContextProperties; this.polarisContext = context; this.staticMetadataManager = staticMetadataManager; - + this.nacosContextProperties = nacosContextProperties; host = polarisContext.getConfig().getGlobal().getAPI().getBindIP(); } @Override public String getServiceId() { - return polarisDiscoveryProperties.getService(); + if (Objects.isNull(nacosContextProperties)) { + return polarisDiscoveryProperties.getService(); + } + else { + String group = nacosContextProperties.getGroup(); + if (StringUtils.isNotBlank(group) && !DEFAULT_GROUP.equals(group)) { + return String.format(GROUP_SERVER_ID_FORMAT, group, polarisDiscoveryProperties.getService()); + } + else { + return polarisDiscoveryProperties.getService(); + } + } } @Override @@ -111,6 +132,12 @@ public class PolarisRegistration implements Registration { instanceMetadata.put(METADATA_KEY_IP, host); instanceMetadata.put(METADATA_KEY_ADDRESS, host + ":" + polarisDiscoveryProperties.getPort()); + // put internal-nacos-cluster if necessary + String clusterName = nacosContextProperties.getClusterName(); + if (StringUtils.isNotBlank(clusterName) && !DEFAULT_CLUSTER.equals(clusterName)) { + instanceMetadata.put(NACOS_CLUSTER, clusterName); + } + instanceMetadata.putAll(staticMetadataManager.getMergedStaticMetadata()); this.metadata = instanceMetadata; @@ -136,12 +163,14 @@ public class PolarisRegistration implements Registration { boolean registerEnabled = false; if (null != polarisDiscoveryProperties) { - registerEnabled |= polarisDiscoveryProperties.isRegisterEnabled(); + registerEnabled = polarisDiscoveryProperties.isRegisterEnabled(); } if (null != consulContextProperties && consulContextProperties.isEnabled()) { registerEnabled |= consulContextProperties.isRegister(); } - + if (null != nacosContextProperties && nacosContextProperties.isEnabled()) { + registerEnabled |= nacosContextProperties.isRegisterEnabled(); + } return registerEnabled; } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java index b5203f97c..129450bca 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistryAutoConfiguration.java @@ -23,6 +23,7 @@ import com.tencent.cloud.polaris.PolarisDiscoveryProperties; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryAutoConfiguration; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; import com.tencent.cloud.polaris.extend.consul.ConsulContextProperties; +import com.tencent.cloud.polaris.extend.nacos.NacosContextProperties; import com.tencent.polaris.client.api.SDKContext; import org.springframework.beans.factory.annotation.Autowired; @@ -61,8 +62,8 @@ public class PolarisServiceRegistryAutoConfiguration { public PolarisRegistration polarisRegistration( PolarisDiscoveryProperties polarisDiscoveryProperties, @Autowired(required = false) ConsulContextProperties consulContextProperties, - SDKContext context, StaticMetadataManager staticMetadataManager) { - return new PolarisRegistration(polarisDiscoveryProperties, consulContextProperties, context, staticMetadataManager); + SDKContext context, StaticMetadataManager staticMetadataManager, NacosContextProperties nacosContextProperties) { + return new PolarisRegistration(polarisDiscoveryProperties, consulContextProperties, context, staticMetadataManager, nacosContextProperties); } @Bean diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 115585d91..12a535855 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -65,6 +65,50 @@ "type": "java.lang.Long", "defaultValue": 60000, "description": "Millis interval of refresh of service info list. Default: 60000." + }, + { + "name": "spring.cloud.nacos.discovery.enabled", + "type": "java.lang.Boolean", + "sourceType": "com.tencent.cloud.polaris.extend.nacos.NacosContextProperties", + "defaultValue": false + }, + { + "name": "spring.cloud.nacos.discovery.group", + "type": "java.lang.String", + "description": "group name for nacos.", + "sourceType": "com.tencent.cloud.polaris.extend.nacos.NacosContextProperties", + "defaultValue": "DEFAULT_GROUP" + }, + { + "name": "spring.cloud.nacos.discovery.password", + "type": "java.lang.String", + "description": "the nacos authentication password.", + "sourceType": "com.tencent.cloud.polaris.extend.nacos.NacosContextProperties" + }, + { + "name": "spring.cloud.nacos.discovery.register-enabled", + "type": "java.lang.Boolean", + "description": "if you just want to subscribe on nacos , but don't want to register your service, set it to false.", + "sourceType": "com.tencent.cloud.polaris.extend.nacos.NacosContextProperties", + "defaultValue": false + }, + { + "name": "spring.cloud.nacos.discovery.server-addr", + "type": "java.lang.String", + "description": "nacos discovery server address.", + "sourceType": "com.tencent.cloud.polaris.extend.nacos.NacosContextProperties" + }, + { + "name": "spring.cloud.nacos.discovery.username", + "type": "java.lang.String", + "description": "the nacos authentication username.", + "sourceType": "com.tencent.cloud.polaris.extend.nacos.NacosContextProperties" + }, + { + "name": "spring.cloud.nacos.discovery.cluster-name", + "type": "java.lang.String", + "description": "the nacos authentication cluster-name.", + "sourceType": "com.tencent.cloud.polaris.extend.nacos.NacosContextProperties" } ] } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java index 303f39736..bfd67879c 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/discovery/PolarisDiscoveryClientTest.java @@ -62,13 +62,12 @@ public class PolarisDiscoveryClientTest { @Test public void testGetServices() { - when(polarisServiceDiscovery.getServices()).thenReturn(singletonList(SERVICE_PROVIDER)); List services = client.getServices(); - assertThat(services).contains(SERVICE_PROVIDER).size().isEqualTo(1); - + assertThat(services).size().isEqualTo(1); + assertThat(services.contains(SERVICE_PROVIDER)).isTrue(); } @Test diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/extend/nacos/NacosContextPropertiesTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/extend/nacos/NacosContextPropertiesTest.java new file mode 100644 index 000000000..97588194a --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/extend/nacos/NacosContextPropertiesTest.java @@ -0,0 +1,91 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + */ + +package com.tencent.cloud.polaris.extend.nacos; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import com.tencent.polaris.api.config.plugin.DefaultPlugins; +import com.tencent.polaris.client.api.SDKContext; +import com.tencent.polaris.factory.config.global.ServerConnectorConfigImpl; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.util.CollectionUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for {@link NacosContextProperties}. + * + * @author lingxiao.wlx + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = NacosContextPropertiesTest.TestApplication.class) +@ActiveProfiles("test") +public class NacosContextPropertiesTest { + + @Autowired + private NacosContextProperties nacosContextProperties; + + @Autowired + private SDKContext sdkContext; + + @Test + public void testDefaultInitialization() { + assertThat(nacosContextProperties).isNotNull(); + assertThat(nacosContextProperties.isEnabled()).isTrue(); + assertThat(nacosContextProperties.getServerAddr()).isEqualTo("127.0.0.1:8848"); + assertThat(nacosContextProperties.isRegisterEnabled()).isTrue(); + assertThat(nacosContextProperties.isDiscoveryEnabled()).isTrue(); + assertThat(nacosContextProperties.getGroup()).isNotBlank(); + assertThat(nacosContextProperties.getClusterName()).isNotBlank(); + } + + @Test + public void testModify() { + assertThat(sdkContext).isNotNull(); + com.tencent.polaris.api.config.Configuration configuration = sdkContext.getConfig(); + List serverConnectorConfigs = configuration.getGlobal().getServerConnectors(); + Optional optionalServerConnectorConfig = serverConnectorConfigs.stream().filter( + item -> "nacos".equals(item.getId()) + ).findAny(); + assertThat(optionalServerConnectorConfig.isPresent()).isTrue(); + ServerConnectorConfigImpl serverConnectorConfig = optionalServerConnectorConfig.get(); + if (!CollectionUtils.isEmpty(serverConnectorConfig.getAddresses())) { + assertThat(nacosContextProperties.getServerAddr().equals(serverConnectorConfig.getAddresses().get(0))).isTrue(); + } + assertThat(DefaultPlugins.SERVER_CONNECTOR_NACOS.equals(serverConnectorConfig.getProtocol())).isTrue(); + + Map metadata = serverConnectorConfig.getMetadata(); + assertThat(metadata.get(NacosConfigModifier.USERNAME)).isEqualTo(nacosContextProperties.getUsername()); + assertThat(metadata.get(NacosConfigModifier.PASSWORD)).isEqualTo(nacosContextProperties.getPassword()); + assertThat(metadata.get(NacosConfigModifier.CONTEXT_PATH)).isEqualTo(nacosContextProperties.getContextPath()); + } + + @SpringBootApplication + protected static class TestApplication { + } +} diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationTest.java b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationTest.java index 420f61569..20ce66b8b 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationTest.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/java/com/tencent/cloud/polaris/registry/PolarisRegistrationTest.java @@ -23,6 +23,7 @@ import java.util.Map; import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; import com.tencent.cloud.polaris.extend.consul.ConsulContextProperties; +import com.tencent.cloud.polaris.extend.nacos.NacosContextProperties; import com.tencent.polaris.api.config.Configuration; import com.tencent.polaris.api.config.global.APIConfig; import com.tencent.polaris.api.config.global.GlobalConfig; @@ -38,6 +39,7 @@ import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * Test for {@link PolarisRegistration}. @@ -49,6 +51,8 @@ public class PolarisRegistrationTest { private PolarisRegistration polarisRegistration; + NacosContextProperties nacosContextProperties = mock(NacosContextProperties.class); + @Before public void setUp() { // mock PolarisDiscoveryProperties @@ -76,7 +80,7 @@ public class PolarisRegistrationTest { doReturn(Collections.singletonMap("key1", "value1")).when(staticMetadataManager).getMergedStaticMetadata(); polarisRegistration = new PolarisRegistration(polarisDiscoveryProperties, consulContextProperties, - polarisContext, staticMetadataManager); + polarisContext, staticMetadataManager, nacosContextProperties); } @Test @@ -127,4 +131,24 @@ public class PolarisRegistrationTest { public void testToString() { System.out.println(polarisRegistration); } + + @Test + public void testGetNacosServiceId() { + String groupName = "group"; + String format = "%s__%s"; + when(nacosContextProperties.getGroup()).thenReturn(groupName); + String serviceId = polarisRegistration.getServiceId(); + assertThat(String.format(format, groupName, SERVICE_PROVIDER).equals(serviceId)); + } + + @Test + public void testGetNacosMetadata() { + String clusterName = "cluster"; + when(nacosContextProperties.getClusterName()).thenReturn(clusterName); + Map metadata = polarisRegistration.getMetadata(); + assertThat(metadata).isNotNull(); + assertThat(metadata).isNotEmpty(); + assertThat(metadata.size()).isEqualTo(4); + assertThat(metadata.get("nacos.cluster")).isEqualTo(clusterName); + } } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/test/resources/application-test.yml b/spring-cloud-starter-tencent-polaris-discovery/src/test/resources/application-test.yml index 8fbdbcc48..52752ef59 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/test/resources/application-test.yml +++ b/spring-cloud-starter-tencent-polaris-discovery/src/test/resources/application-test.yml @@ -22,3 +22,14 @@ spring: service-name: ${spring.application.name} ip-address: 127.0.0.1 prefer-ip-address: true + nacos: + enabled: true + context-path: /nacos + discovery: + enabled: true + register-enabled: true + group: polaris + server-addr: 127.0.0.1:8848 + username: nacos + password: nacos + cluster-name: polaris diff --git a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilter.java b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilter.java index 7cc6fdeb9..8612a635a 100644 --- a/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilter.java +++ b/spring-cloud-starter-tencent-polaris-router/src/main/java/com/tencent/cloud/polaris/router/scg/PolarisReactiveLoadBalancerClientFilter.java @@ -181,6 +181,7 @@ public class PolarisReactiveLoadBalancerClientFilter extends ReactiveLoadBalance new ResponseData(exchange.getResponse(), new RequestData(exchange.getRequest())))))); } + @Override protected URI reconstructURI(ServiceInstance serviceInstance, URI original) { return LoadBalancerUriTools.reconstructURI(serviceInstance, original); } 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 ef706673f..bc2e20c9d 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 @@ -19,16 +19,34 @@ package com.tencent.cloud.common.util; import java.lang.reflect.Field; +import org.springframework.util.ClassUtils; + +import static java.util.Locale.ENGLISH; + /** * Reflection Utils. * * @author Haotian Zhang */ -public final class ReflectionUtils { +public final class ReflectionUtils extends org.springframework.util.ReflectionUtils { + private final static String SET_PREFIX = "set"; private ReflectionUtils() { } + public static boolean writableBeanField(Field field) { + String fieldName = field.getName(); + String setMethodName = SET_PREFIX + capitalize(fieldName); + return ClassUtils.hasMethod(field.getDeclaringClass(), setMethodName, field.getType()); + } + + public static String capitalize(String name) { + if (name == null || name.length() == 0) { + return name; + } + return name.substring(0, 1).toUpperCase(ENGLISH) + name.substring(1); + } + public static Object getFieldValue(Object instance, String fieldName) { Field field = org.springframework.util.ReflectionUtils.findField(instance.getClass(), fieldName); if (field == null) { diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index 52098b299..ebaf8f5d1 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -78,7 +78,7 @@ 1.2.11 4.5.1 1.12.10 - 3.16.1 + 3.21.7 1.69 2.0.1 diff --git a/spring-cloud-tencent-examples/polaris-config-data-example/src/main/java/com/tencent/cloud/polaris/config/example/PolarisConfigDataExampleApplication.java b/spring-cloud-tencent-examples/polaris-config-data-example/src/main/java/com/tencent/cloud/polaris/config/example/PolarisConfigDataExampleApplication.java index 78eec0f17..f2183bd8d 100644 --- a/spring-cloud-tencent-examples/polaris-config-data-example/src/main/java/com/tencent/cloud/polaris/config/example/PolarisConfigDataExampleApplication.java +++ b/spring-cloud-tencent-examples/polaris-config-data-example/src/main/java/com/tencent/cloud/polaris/config/example/PolarisConfigDataExampleApplication.java @@ -5,7 +5,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author wlx - * @date 2022/7/6 9:15 PM */ @SpringBootApplication public class PolarisConfigDataExampleApplication { diff --git a/spring-cloud-tencent-examples/polaris-config-example/src/main/java/com/tencent/cloud/polaris/config/example/Person.java b/spring-cloud-tencent-examples/polaris-config-example/src/main/java/com/tencent/cloud/polaris/config/example/Person.java index 1a88235de..3b3348ea4 100644 --- a/spring-cloud-tencent-examples/polaris-config-example/src/main/java/com/tencent/cloud/polaris/config/example/Person.java +++ b/spring-cloud-tencent-examples/polaris-config-example/src/main/java/com/tencent/cloud/polaris/config/example/Person.java @@ -34,6 +34,8 @@ public class Person { private int age; + private boolean isDirector; + public String getName() { return name; } @@ -50,8 +52,17 @@ public class Person { this.age = age; } + + public boolean isDirector() { + return isDirector; + } + + public void setIsDirector(boolean isDirector) { + this.isDirector = isDirector; + } + @Override public String toString() { - return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; + return "User{" + "name='" + name + '\'' + ", age=" + age + ", isDirector=" + isDirector + '\'' + '}'; } } diff --git a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml index 22c330986..c36f4ac20 100644 --- a/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml +++ b/spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service/src/main/resources/bootstrap.yml @@ -41,6 +41,17 @@ spring: # service-name: ${spring.application.name} # ip-address: localhost # prefer-ip-address: true +# nacos: +# enabled: true +# context-path: /nacos +# discovery: +# enabled: true +# register-enabled: true +# group: polaris +# server-addr: 127.0.0.1:8848 +# username: nacos +# password: nacos +# cluster-name: polaris #eureka: # client: # serviceUrl: diff --git a/spring-cloud-tencent-polaris-context/pom.xml b/spring-cloud-tencent-polaris-context/pom.xml index 944f04a04..e59c2a278 100644 --- a/spring-cloud-tencent-polaris-context/pom.xml +++ b/spring-cloud-tencent-polaris-context/pom.xml @@ -69,6 +69,11 @@ connector-consul + + com.tencent.polaris + connector-nacos + + com.tencent.polaris connector-composite