Merge branch 'hoxton' into h/nacos

pull/758/head
Haotian Zhang 3 years ago committed by GitHub
commit c3d0b5474b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -14,6 +14,6 @@
- [fix:fix discovery junit.](https://github.com/Tencent/spring-cloud-tencent/pull/729)
- [adapt polaris-java 1.10.1 version](https://github.com/Tencent/spring-cloud-tencent/pull/747)
- [Optimize: change RouteArgument.buildCustom to RouteArgument.fromLabel](https://github.com/Tencent/spring-cloud-tencent/pull/751)
- [Feature: support nacos registry](https://github.com/Tencent/spring-cloud-tencent/pull/758)
- [Optimize: support delete config for ConfigurationProperties bean ](https://github.com/Tencent/spring-cloud-tencent/pull/756)
- [Feature: support nacos registry](https://github.com/Tencent/spring-cloud-tencent/pull/758)
- [Test:add sct-stater-polaris-router junit.](https://github.com/Tencent/spring-cloud-tencent/pull/768)

@ -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,15 +39,18 @@ 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.
* @author weihubeats 2022-7-10
*/
public class AffectedConfigurationPropertiesRebinder extends ConfigurationPropertiesRebinder {
private static final Logger LOGGER = LoggerFactory.getLogger(AffectedConfigurationPropertiesRebinder.class);
private ApplicationContext applicationContext;
private Map<String, ConfigurationPropertiesBean> propertiesBeans = new HashMap<>();
private final Map<String, Map<String, Object>> propertiesBeanDefaultValues = new ConcurrentHashMap<>();
public AffectedConfigurationPropertiesRebinder(ConfigurationPropertiesBeans beans) {
super(beans);
@ -52,6 +63,7 @@ public class AffectedConfigurationPropertiesRebinder extends ConfigurationProper
this.applicationContext = applicationContext;
propertiesBeans = ConfigurationPropertiesBean.getAll(applicationContext);
initPropertiesBeanDefaultValues(propertiesBeans);
}
@Override
@ -74,8 +86,63 @@ 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<String, Object> 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<String, ConfigurationPropertiesBean> propertiesBeans) {
if (MapUtils.isEmpty(propertiesBeans)) {
return;
}
for (ConfigurationPropertiesBean propertiesBean : propertiesBeans.values()) {
Map<String, Object> 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);
}
}
}

@ -0,0 +1,54 @@
/*
* 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.router.config.properties;
import org.junit.Before;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* test for {@link PolarisMetadataRouterProperties}.
*/
public class PolarisMetadataRouterPropertiesTest {
PolarisMetadataRouterProperties properties;
@Before
public void setUp() {
properties = new PolarisMetadataRouterProperties();
}
@Test
public void isEnabled() {
assertThat(properties.isEnabled()).isEqualTo(true);
}
@Test
public void setEnabled() {
properties.setEnabled(false);
assertThat(properties.isEnabled()).isEqualTo(false);
}
@Test
public void testToString() {
assertThat(properties.toString())
.isEqualTo("PolarisMetadataRouterProperties{enabled=true}");
}
}

@ -0,0 +1,56 @@
/*
* 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.router.config.properties;
import org.junit.Before;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* test for {@link PolarisNearByRouterProperties}.
*/
public class PolarisNearByRouterPropertiesTest {
PolarisNearByRouterProperties properties;
@Before
public void setUp() {
properties = new PolarisNearByRouterProperties();
}
@Test
public void isEnabled() {
assertThat(properties.isEnabled()).isEqualTo(true);
}
@Test
public void setEnabled() {
properties.setEnabled(false);
assertThat(properties.isEnabled()).isEqualTo(false);
}
@Test
public void testToString() {
assertThat(properties.toString())
.isEqualTo("PolarisNearByRouterProperties{enabled=true}");
}
}

@ -0,0 +1,55 @@
/*
* 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.router.config.properties;
import org.junit.Before;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* test for {@link PolarisRuleBasedRouterProperties}.
*/
public class PolarisRuleBasedRouterPropertiesTest {
PolarisRuleBasedRouterProperties properties;
@Before
public void setUp() {
properties = new PolarisRuleBasedRouterProperties();
}
@Test
public void isEnabled() {
assertThat(properties.isEnabled()).isEqualTo(true);
}
@Test
public void setEnabled() {
properties.setEnabled(false);
assertThat(properties.isEnabled()).isEqualTo(false);
}
@Test
public void testToString() {
assertThat(properties.toString())
.isEqualTo("PolarisNearByRouterProperties{enabled=true}");
}
}

@ -0,0 +1,65 @@
/*
* 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.router.endpoint;
import com.tencent.cloud.polaris.context.ServiceRuleManager;
import com.tencent.polaris.client.api.SDKContext;
import org.junit.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
/**
* test for {@link PolarisRouterEndpointAutoConfiguration}.
* @author dongyinuo
*/
public class PolarisRouterEndpointAutoConfigurationTests {
private ServiceRuleManager serviceRuleManager;
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
TestServiceRuleManagerConfiguration.class,
PolarisRouterEndpointAutoConfiguration.class))
.withPropertyValues("endpoints.polaris-router.enabled=true");
@Test
public void polarisRouterEndpoint() {
contextRunner.run(context -> {
assertThat(context).hasSingleBean(PolarisRouterEndpointAutoConfiguration.class);
});
}
@Configuration
static class TestServiceRuleManagerConfiguration {
@Bean
public ServiceRuleManager serviceRuleManager(SDKContext sdkContext) {
return new ServiceRuleManager(sdkContext);
}
@Bean
public SDKContext sdkContext() {
return SDKContext.initContext();
}
}
}

@ -46,6 +46,7 @@ import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
@ -72,6 +73,8 @@ public class RouterLabelFeignInterceptorTest {
Collections.singletonList(routerLabelResolver),
staticMetadataManager, routerRuleLabelResolver, polarisContextProperties);
assertThat(routerLabelFeignInterceptor.getOrder()).isEqualTo(0);
// mock request template
RequestTemplate requestTemplate = new RequestTemplate();
String headerUidKey = "uid";

@ -52,6 +52,7 @@ import org.springframework.mock.web.server.MockServerWebExchange;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ -88,7 +89,7 @@ public class PolarisLoadBalancerClientFilterTest {
mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString()))
.thenReturn(callerService);
MetadataContext metadataContext = Mockito.mock(MetadataContext.class);
MetadataContext metadataContext = mock(MetadataContext.class);
// mock transitive metadata
Map<String, String> transitiveLabels = new HashMap<>();

@ -19,16 +19,37 @@ 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) {

@ -18,6 +18,8 @@
package com.tencent.cloud.polaris.config.example;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ -34,6 +36,10 @@ public class Person {
private int age;
private boolean director;
private List<String> students;
public String getName() {
return name;
}
@ -50,8 +56,29 @@ public class Person {
this.age = age;
}
public boolean isDirector() {
return director;
}
public void setDirector(boolean director) {
this.director = director;
}
public List<String> getStudents() {
return students;
}
public void setStudents(List<String> students) {
this.students = students;
}
@Override
public String toString() {
return "User{" + "name='" + name + '\'' + ", age=" + age + '}';
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", director=" + director +
", students=" + students +
'}';
}
}

Loading…
Cancel
Save