add config refresh type switch & catch exception for traffic staining (#469)

* add config refresh type switch & catch exception for traffic staning

* add change log
pull/472/head
lepdou 2 years ago committed by GitHub
parent 7036f908e1
commit 7699ed16f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -20,3 +20,4 @@
- [Feature: Add router actuate endpoint](https://github.com/Tencent/spring-cloud-tencent/pull/464) - [Feature: Add router actuate endpoint](https://github.com/Tencent/spring-cloud-tencent/pull/464)
- [feat:rename the configuration of reporter.](https://github.com/Tencent/spring-cloud-tencent/pull/465) - [feat:rename the configuration of reporter.](https://github.com/Tencent/spring-cloud-tencent/pull/465)
- [docs:update mvnw.](https://github.com/Tencent/spring-cloud-tencent/pull/466) - [docs:update mvnw.](https://github.com/Tencent/spring-cloud-tencent/pull/466)
- [Feature: add config refresh type switch & catch exception for traffic staining.](https://github.com/Tencent/spring-cloud-tencent/pull/469)

@ -35,6 +35,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.SearchStrategy; import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.cloud.context.properties.ConfigurationPropertiesBeans; import org.springframework.cloud.context.properties.ConfigurationPropertiesBeans;
import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -53,9 +54,10 @@ public class PolarisConfigAutoConfiguration {
PolarisConfigProperties polarisConfigProperties, PolarisConfigProperties polarisConfigProperties,
PolarisPropertySourceManager polarisPropertySourceManager, PolarisPropertySourceManager polarisPropertySourceManager,
SpringValueRegistry springValueRegistry, SpringValueRegistry springValueRegistry,
PlaceholderHelper placeholderHelper) { PlaceholderHelper placeholderHelper,
ContextRefresher contextRefresher) {
return new PolarisPropertySourceAutoRefresher(polarisConfigProperties, return new PolarisPropertySourceAutoRefresher(polarisConfigProperties,
polarisPropertySourceManager, springValueRegistry, placeholderHelper); polarisPropertySourceManager, springValueRegistry, placeholderHelper, contextRefresher);
} }
@Bean @Bean

@ -25,6 +25,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import com.tencent.cloud.common.util.JacksonUtils; import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
import com.tencent.cloud.polaris.config.enums.RefreshType;
import com.tencent.cloud.polaris.config.spring.property.PlaceholderHelper; import com.tencent.cloud.polaris.config.spring.property.PlaceholderHelper;
import com.tencent.cloud.polaris.config.spring.property.SpringValue; import com.tencent.cloud.polaris.config.spring.property.SpringValue;
import com.tencent.cloud.polaris.config.spring.property.SpringValueRegistry; import com.tencent.cloud.polaris.config.spring.property.SpringValueRegistry;
@ -40,6 +41,7 @@ import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
@ -61,6 +63,8 @@ public class PolarisPropertySourceAutoRefresher
private final PolarisPropertySourceManager polarisPropertySourceManager; private final PolarisPropertySourceManager polarisPropertySourceManager;
private final ContextRefresher contextRefresher;
private final AtomicBoolean registered = new AtomicBoolean(false); private final AtomicBoolean registered = new AtomicBoolean(false);
private ConfigurableApplicationContext context; private ConfigurableApplicationContext context;
@ -70,16 +74,17 @@ public class PolarisPropertySourceAutoRefresher
private ConfigurableBeanFactory beanFactory; private ConfigurableBeanFactory beanFactory;
private final PlaceholderHelper placeholderHelper; private final PlaceholderHelper placeholderHelper;
public PolarisPropertySourceAutoRefresher( public PolarisPropertySourceAutoRefresher(
PolarisConfigProperties polarisConfigProperties, PolarisConfigProperties polarisConfigProperties,
PolarisPropertySourceManager polarisPropertySourceManager, PolarisPropertySourceManager polarisPropertySourceManager,
SpringValueRegistry springValueRegistry, SpringValueRegistry springValueRegistry,
PlaceholderHelper placeholderHelper) { PlaceholderHelper placeholderHelper,
ContextRefresher contextRefresher) {
this.polarisConfigProperties = polarisConfigProperties; this.polarisConfigProperties = polarisConfigProperties;
this.polarisPropertySourceManager = polarisPropertySourceManager; this.polarisPropertySourceManager = polarisPropertySourceManager;
this.springValueRegistry = springValueRegistry; this.springValueRegistry = springValueRegistry;
this.placeholderHelper = placeholderHelper; this.placeholderHelper = placeholderHelper;
this.contextRefresher = contextRefresher;
} }
@Override @Override
@ -138,17 +143,25 @@ public class PolarisPropertySourceAutoRefresher
break; break;
} }
Collection<SpringValue> targetValues = springValueRegistry.get(beanFactory, changedKey); if (polarisConfigProperties.getRefreshType() == RefreshType.REFLECT) {
if (targetValues == null || targetValues.isEmpty()) { Collection<SpringValue> targetValues = springValueRegistry.get(beanFactory, changedKey);
continue; if (targetValues == null || targetValues.isEmpty()) {
} continue;
// update the value }
for (SpringValue val : targetValues) { // update the attribute with @Value annotation
updateSpringValue(val); for (SpringValue val : targetValues) {
updateSpringValue(val);
}
} }
}
if (polarisConfigProperties.getRefreshType() == RefreshType.REFLECT) {
// update @ConfigurationProperties beans
context.publishEvent(new EnvironmentChangeEvent(context, configKVFileChangeEvent.changedKeys()));
}
else {
contextRefresher.refresh();
} }
context.publishEvent(new EnvironmentChangeEvent(context, configKVFileChangeEvent.changedKeys()));
}); });
} }
} }

@ -19,6 +19,8 @@ package com.tencent.cloud.polaris.config.config;
import java.util.List; import java.util.List;
import com.tencent.cloud.polaris.config.enums.RefreshType;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
/** /**
@ -50,6 +52,11 @@ public class PolarisConfigProperties {
*/ */
private boolean autoRefresh = true; private boolean autoRefresh = true;
/**
* Attribute refresh type.
*/
private RefreshType refreshType = RefreshType.REFRESH_CONTEXT;
/** /**
* List of injected configuration files. * List of injected configuration files.
*/ */
@ -87,6 +94,14 @@ public class PolarisConfigProperties {
this.autoRefresh = autoRefresh; this.autoRefresh = autoRefresh;
} }
public RefreshType getRefreshType() {
return refreshType;
}
public void setRefreshType(RefreshType refreshType) {
this.refreshType = refreshType;
}
public List<ConfigFileGroup> getGroups() { public List<ConfigFileGroup> getGroups() {
return groups; return groups;
} }

@ -0,0 +1,34 @@
/*
* 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.config.enums;
/**
* Attribute refresh type when config updated.
* @author lepdou 2022-07-26
*/
public enum RefreshType {
/**
* refresh spring context.
*/
REFRESH_CONTEXT,
/**
* Dynamically refresh a bean's properties via reflection calls.
*/
REFLECT
}

@ -47,6 +47,12 @@
"type": "com.tencent.cloud.polaris.config.enums.RefreshBehavior", "type": "com.tencent.cloud.polaris.config.enums.RefreshBehavior",
"defaultValue": "all_beans", "defaultValue": "all_beans",
"description": "ConfigurationPropertiesBean refresh behavior." "description": "ConfigurationPropertiesBean refresh behavior."
},
{
"name": "spring.cloud.polaris.config.refresh-type",
"type": "com.tencent.cloud.polaris.config.enums.RefreshType",
"defaultValue": "refresh_context",
"description": "Attribute refresh type when config updated. refresh_context or reflect."
} }
] ]
} }

@ -26,6 +26,7 @@ import java.util.Map;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
import com.tencent.cloud.polaris.config.enums.RefreshType;
import com.tencent.cloud.polaris.config.spring.property.PlaceholderHelper; import com.tencent.cloud.polaris.config.spring.property.PlaceholderHelper;
import com.tencent.cloud.polaris.config.spring.property.SpringValue; import com.tencent.cloud.polaris.config.spring.property.SpringValue;
import com.tencent.cloud.polaris.config.spring.property.SpringValueRegistry; import com.tencent.cloud.polaris.config.spring.property.SpringValueRegistry;
@ -74,8 +75,9 @@ public class PolarisPropertiesSourceAutoRefresherTest {
@Test @Test
public void testConfigFileChanged() throws Exception { public void testConfigFileChanged() throws Exception {
PolarisPropertySourceAutoRefresher refresher = new PolarisPropertySourceAutoRefresher(polarisConfigProperties, PolarisPropertySourceAutoRefresher refresher = new PolarisPropertySourceAutoRefresher(polarisConfigProperties,
polarisPropertySourceManager, springValueRegistry, placeholderHelper); polarisPropertySourceManager, springValueRegistry, placeholderHelper, contextRefresher);
when(polarisConfigProperties.getRefreshType()).thenReturn(RefreshType.REFLECT);
ConfigurableApplicationContext applicationContext = mock(ConfigurableApplicationContext.class); ConfigurableApplicationContext applicationContext = mock(ConfigurableApplicationContext.class);
ConfigurableListableBeanFactory beanFactory = mock(ConfigurableListableBeanFactory.class); ConfigurableListableBeanFactory beanFactory = mock(ConfigurableListableBeanFactory.class);
TypeConverter typeConverter = mock(TypeConverter.class); TypeConverter typeConverter = mock(TypeConverter.class);

@ -64,5 +64,6 @@ spring:
logging: logging:
level: level:
com.tencent.cloud.plugin.gateway: debug
org.springframework.cloud.gateway: info org.springframework.cloud.gateway: info
com.tencent.cloud.polaris: debug com.tencent.cloud.polaris: debug

@ -3,7 +3,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<artifactId>polaris-router-featureenv-base</artifactId> <artifactId>base</artifactId>
<groupId>com.tencent.cloud</groupId> <groupId>com.tencent.cloud</groupId>
<version>${revision}</version> <version>${revision}</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>

@ -3,7 +3,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<artifactId>polaris-router-featureenv-base</artifactId> <artifactId>base</artifactId>
<groupId>com.tencent.cloud</groupId> <groupId>com.tencent.cloud</groupId>
<version>${revision}</version> <version>${revision}</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>

@ -3,7 +3,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<artifactId>polaris-router-featureenv-base</artifactId> <artifactId>base</artifactId>
<groupId>com.tencent.cloud</groupId> <groupId>com.tencent.cloud</groupId>
<version>${revision}</version> <version>${revision}</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>

@ -10,7 +10,7 @@
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>polaris-router-featureenv-base</artifactId> <artifactId>base</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<modules> <modules>

@ -26,6 +26,9 @@ import java.util.Map;
import com.tencent.cloud.common.constant.MetadataConstant; import com.tencent.cloud.common.constant.MetadataConstant;
import com.tencent.cloud.common.metadata.MetadataContext; import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.util.JacksonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GatewayFilterChain;
@ -43,6 +46,8 @@ import static org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter.R
*/ */
public class TrafficStainingGatewayFilter implements GlobalFilter, Ordered { public class TrafficStainingGatewayFilter implements GlobalFilter, Ordered {
private static final Logger LOGGER = LoggerFactory.getLogger(TrafficStainingGatewayFilter.class);
private final List<TrafficStainer> trafficStainers; private final List<TrafficStainer> trafficStainers;
public TrafficStainingGatewayFilter(List<TrafficStainer> trafficStainers) { public TrafficStainingGatewayFilter(List<TrafficStainer> trafficStainers) {
@ -87,13 +92,23 @@ public class TrafficStainingGatewayFilter implements GlobalFilter, Ordered {
Map<String, String> getStainedLabels(ServerWebExchange exchange) { Map<String, String> getStainedLabels(ServerWebExchange exchange) {
Map<String, String> stainedLabels = new HashMap<>(); Map<String, String> stainedLabels = new HashMap<>();
int size = trafficStainers.size(); int size = trafficStainers.size();
TrafficStainer stainer = null;
for (int i = size - 1; i >= 0; i--) { for (int i = size - 1; i >= 0; i--) {
TrafficStainer stainer = trafficStainers.get(i); try {
Map<String, String> labels = stainer.apply(exchange); stainer = trafficStainers.get(i);
if (!CollectionUtils.isEmpty(labels)) { Map<String, String> labels = stainer.apply(exchange);
stainedLabels.putAll(labels); if (!CollectionUtils.isEmpty(labels)) {
stainedLabels.putAll(labels);
}
}
catch (Exception e) {
if (stainer != null) {
LOGGER.error("[SCT] traffic stained error. stainer = {}", stainer.getClass().getName(), e);
}
} }
} }
LOGGER.debug("[SCT] traffic stained labels. {}", JacksonUtils.serialize2Json(stainedLabels));
return stainedLabels; return stainedLabels;
} }

@ -9,7 +9,7 @@
{ {
"name": "spring.cloud.tencent.plugin.scg.staining.enabled", "name": "spring.cloud.tencent.plugin.scg.staining.enabled",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
"defaultValue": true, "defaultValue": false,
"description": "the switch for spring cloud gateway staining plugin." "description": "the switch for spring cloud gateway staining plugin."
}, },
{ {

Loading…
Cancel
Save