From 355716e191b1a4d3c18b7a6b57fb02af36aedb72 Mon Sep 17 00:00:00 2001 From: shedfreewu <49236872+shedfreewu@users.noreply.github.com> Date: Mon, 14 Apr 2025 17:37:50 +0800 Subject: [PATCH] feat: support config event (#1532) --- CHANGELOG.md | 1 + .../PolarisConfigAutoConfiguration.java | 10 ++-- .../PolarisConfigPropertyAutoRefresher.java | 48 ++++++++++++++++++- ...olarisRefreshAffectedContextRefresher.java | 5 +- .../PolarisRefreshEntireContextRefresher.java | 6 ++- .../config/adapter/MockedConfigKVFile.java | 5 ++ ...arisPropertiesSourceAutoRefresherTest.java | 26 ++++++++-- ...arisRefreshEntireContextRefresherTest.java | 7 ++- .../PolarisAutoServiceRegistration.java | 7 ++- spring-cloud-tencent-dependencies/pom.xml | 2 +- 10 files changed, 98 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ce657154..daeaa945e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,3 +11,4 @@ - [docs:update JDK version configuration in GitHub Actions.](https://github.com/Tencent/spring-cloud-tencent/pull/1510) - [fix:fix watch tsf config, fix bean refresh with RefreshScope and ConfigurationProperties.](https://github.com/Tencent/spring-cloud-tencent/pull/1511) - [docs:simplify GitHub Actions.](https://github.com/Tencent/spring-cloud-tencent/pull/1514) +- [feat: support config event.](https://github.com/Tencent/spring-cloud-tencent/pull/1532) diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java index 3fee72002..92c6fda80 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java @@ -29,6 +29,7 @@ import com.tencent.cloud.polaris.config.logger.PolarisConfigLoggerApplicationLis import com.tencent.cloud.polaris.config.spring.annotation.SpringValueProcessor; import com.tencent.cloud.polaris.config.spring.property.PlaceholderHelper; import com.tencent.cloud.polaris.config.spring.property.SpringValueRegistry; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.polaris.configuration.api.core.ConfigFileService; import org.springframework.boot.autoconfigure.AutoConfigureBefore; @@ -77,9 +78,9 @@ public class PolarisConfigAutoConfiguration { @ConditionalOnMissingBean(search = SearchStrategy.CURRENT) public PolarisConfigPropertyRefresher polarisRefreshContextPropertySourceAutoRefresher( PolarisConfigProperties polarisConfigProperties, SpringValueRegistry springValueRegistry, - ConfigFileService configFileService, ContextRefresher contextRefresher) { + ConfigFileService configFileService, ContextRefresher contextRefresher, PolarisSDKContextManager polarisSDKContextManager) { return new PolarisRefreshEntireContextRefresher(polarisConfigProperties, - springValueRegistry, configFileService, contextRefresher); + springValueRegistry, configFileService, contextRefresher, polarisSDKContextManager.getSDKContext()); } @Bean @@ -105,9 +106,10 @@ public class PolarisConfigAutoConfiguration { @Bean public PolarisConfigPropertyRefresher polarisReflectPropertySourceAutoRefresher( PolarisConfigProperties polarisConfigProperties, SpringValueRegistry springValueRegistry, - PlaceholderHelper placeholderHelper, ConfigFileService configFileService, ContextRefresher contextRefresher) { + PlaceholderHelper placeholderHelper, ConfigFileService configFileService, + ContextRefresher contextRefresher, PolarisSDKContextManager polarisSDKContextManager) { return new PolarisRefreshAffectedContextRefresher(polarisConfigProperties, - springValueRegistry, placeholderHelper, configFileService, contextRefresher); + springValueRegistry, placeholderHelper, configFileService, contextRefresher, polarisSDKContextManager.getSDKContext()); } } } diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java index d37604e8d..1445834df 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java @@ -17,6 +17,7 @@ package com.tencent.cloud.polaris.config.adapter; +import java.time.LocalDateTime; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -29,10 +30,16 @@ import java.util.stream.Collectors; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; import com.tencent.cloud.polaris.config.logger.PolarisConfigLoggerContext; import com.tencent.cloud.polaris.config.utils.PolarisPropertySourceUtils; +import com.tencent.polaris.api.plugin.configuration.ConfigFile; +import com.tencent.polaris.api.plugin.event.ConfigEvent; +import com.tencent.polaris.api.plugin.event.EventConstants; +import com.tencent.polaris.client.api.SDKContext; +import com.tencent.polaris.client.flow.BaseFlow; import com.tencent.polaris.configuration.api.core.ConfigFileGroup; import com.tencent.polaris.configuration.api.core.ConfigFileMetadata; import com.tencent.polaris.configuration.api.core.ConfigFileService; import com.tencent.polaris.configuration.api.core.ConfigKVFile; +import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeEvent; import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeListener; import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo; import com.tencent.polaris.configuration.client.internal.CompositeConfigFile; @@ -61,11 +68,13 @@ public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationL // this class provides customized logic for some customers to configure special business group files private final PolarisConfigCustomExtensionLayer polarisConfigCustomExtensionLayer = PolarisServiceLoaderUtil.getPolarisConfigCustomExtensionLayer(); private final ConfigFileService configFileService; + private final SDKContext context; public PolarisConfigPropertyAutoRefresher(PolarisConfigProperties polarisConfigProperties, - ConfigFileService configFileService) { + ConfigFileService configFileService, SDKContext context) { this.polarisConfigProperties = polarisConfigProperties; this.configFileService = configFileService; + this.context = context; } @Override @@ -157,6 +166,8 @@ public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationL } } refreshConfigurationProperties(changedKeys); + + reportEvent(added); } catch (Exception e) { LOGGER.error("[SCT Config] receive onChange exception,", e); @@ -235,6 +246,9 @@ public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationL } // update @ConfigurationProperties beans refreshConfigurationProperties(configKVFileChangeEvent.changedKeys()); + + reportEvent(listenPolarisPropertySource, configKVFileChangeEvent); + }); } @@ -278,6 +292,38 @@ public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationL return added; } + private void reportEvent(PolarisPropertySource polarisPropertySource, ConfigKVFileChangeEvent configKVFileChangeEvent) { + ConfigEvent.Builder builder = new ConfigEvent.Builder() + .withTimestamp(LocalDateTime.now()) + .withEventType(EventConstants.EventType.CONFIG) + .withEventName(EventConstants.EventName.ConfigUpdated) + .withClientId(context.getExtensions().getValueContext().getClientId()) + .withClientIp(context.getExtensions().getValueContext().getHost()) + .withNamespace(polarisPropertySource.getNamespace()) + .withConfigGroup(polarisPropertySource.getGroup()) + .withConfigVersion(Optional.ofNullable(configKVFileChangeEvent.getConfigFile()).map(ConfigFile::getName).orElse(null)) + .withConfigFileName(polarisPropertySource.getFileName()); + + BaseFlow.reportConfigEvent(context.getExtensions(), builder.build()); + } + + private void reportEvent(Map added) { + for (ConfigFileMetadata configFileMetadata : added.values()) { + ConfigEvent.Builder builder = new ConfigEvent.Builder() + .withTimestamp(LocalDateTime.now()) + .withEventType(EventConstants.EventType.CONFIG) + .withEventName(EventConstants.EventName.ConfigUpdated) + .withClientId(context.getExtensions().getValueContext().getClientId()) + .withClientIp(context.getExtensions().getValueContext().getHost()) + .withNamespace(configFileMetadata.getNamespace()) + .withConfigGroup(configFileMetadata.getFileGroup()) + .withConfigVersion(configFileMetadata.getFileVersion()) + .withConfigFileName(configFileMetadata.getFileName()); + + BaseFlow.reportConfigEvent(context.getExtensions(), builder.build()); + } + } + /** * Just for junit test. */ diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisRefreshAffectedContextRefresher.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisRefreshAffectedContextRefresher.java index 421cd41db..2bf3062e3 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisRefreshAffectedContextRefresher.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisRefreshAffectedContextRefresher.java @@ -24,6 +24,7 @@ import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; 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.SpringValueRegistry; +import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.configuration.api.core.ConfigFileService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,8 +64,8 @@ public class PolarisRefreshAffectedContextRefresher extends PolarisConfigPropert public PolarisRefreshAffectedContextRefresher(PolarisConfigProperties polarisConfigProperties, SpringValueRegistry springValueRegistry, PlaceholderHelper placeholderHelper, - ConfigFileService configFileService, ContextRefresher contextRefresher) { - super(polarisConfigProperties, configFileService); + ConfigFileService configFileService, ContextRefresher contextRefresher, SDKContext context) { + super(polarisConfigProperties, configFileService, context); this.springValueRegistry = springValueRegistry; this.placeholderHelper = placeholderHelper; this.contextRefresher = contextRefresher; diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisRefreshEntireContextRefresher.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisRefreshEntireContextRefresher.java index ea2f55087..6cf3c134d 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisRefreshEntireContextRefresher.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisRefreshEntireContextRefresher.java @@ -22,6 +22,7 @@ import java.util.Set; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; import com.tencent.cloud.polaris.config.spring.property.SpringValueRegistry; +import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.configuration.api.core.ConfigFileService; import org.springframework.beans.BeansException; @@ -46,9 +47,10 @@ public class PolarisRefreshEntireContextRefresher extends PolarisConfigPropertyA private ConfigurableApplicationContext context; public PolarisRefreshEntireContextRefresher(PolarisConfigProperties polarisConfigProperties, - SpringValueRegistry springValueRegistry, ConfigFileService configFileService, ContextRefresher contextRefresher) { + SpringValueRegistry springValueRegistry, ConfigFileService configFileService, + ContextRefresher contextRefresher, SDKContext context) { - super(polarisConfigProperties, configFileService); + super(polarisConfigProperties, configFileService, context); this.springValueRegistry = springValueRegistry; this.contextRefresher = contextRefresher; } diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/MockedConfigKVFile.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/MockedConfigKVFile.java index 5d19faec4..a4813f33c 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/MockedConfigKVFile.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/MockedConfigKVFile.java @@ -192,4 +192,9 @@ public class MockedConfigKVFile implements ConfigKVFile { public String getFileName() { return fileName; } + + @Override + public String getFileVersion() { + return ""; + } } diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertiesSourceAutoRefresherTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertiesSourceAutoRefresherTest.java index 24b5fea1b..36e479243 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertiesSourceAutoRefresherTest.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisPropertiesSourceAutoRefresherTest.java @@ -31,6 +31,9 @@ import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; 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.SpringValueRegistry; +import com.tencent.polaris.api.plugin.common.ValueContext; +import com.tencent.polaris.api.plugin.compose.Extensions; +import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.configuration.api.core.ChangeType; import com.tencent.polaris.configuration.api.core.ConfigFileService; import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeEvent; @@ -80,6 +83,15 @@ public class PolarisPropertiesSourceAutoRefresherTest { @Mock private ContextRefresher contextRefresher; + @Mock + private SDKContext sdkContext; + + @Mock + private Extensions extensions; + + @Mock + private ValueContext valueContext; + @BeforeEach public void setUp() { PolarisPropertySourceManager.clearPropertySources(); @@ -88,7 +100,7 @@ public class PolarisPropertiesSourceAutoRefresherTest { @Test public void testConfigFileChanged() throws Exception { PolarisRefreshAffectedContextRefresher refresher = new PolarisRefreshAffectedContextRefresher( - polarisConfigProperties, springValueRegistry, placeholderHelper, configFileService, contextRefresher); + polarisConfigProperties, springValueRegistry, placeholderHelper, configFileService, contextRefresher, sdkContext); ConfigurableApplicationContext applicationContext = mock(ConfigurableApplicationContext.class); ConfigurableListableBeanFactory beanFactory = mock(ConfigurableListableBeanFactory.class); TypeConverter typeConverter = mock(TypeConverter.class); @@ -107,6 +119,10 @@ public class PolarisPropertiesSourceAutoRefresherTest { when(springValueRegistry.get(any(), any())).thenReturn(springValues); when(polarisConfigProperties.isAutoRefresh()).thenReturn(true); + when(sdkContext.getExtensions()).thenReturn(extensions); + when(extensions.getValueContext()).thenReturn(valueContext); + when(valueContext.getClientId()).thenReturn("mockClientId"); + when(valueContext.getHost()).thenReturn("mockHost"); Map content = new HashMap<>(); content.put("k1", "v1"); @@ -129,7 +145,7 @@ public class PolarisPropertiesSourceAutoRefresherTest { changeInfos.put("k4", changeInfo2); changeInfos.put("logging.level.root", changeInfoLogger); - ConfigKVFileChangeEvent event = new ConfigKVFileChangeEvent(changeInfos); + ConfigKVFileChangeEvent event = new ConfigKVFileChangeEvent(changeInfos, null); refresher.onApplicationEvent(null); file.fireChangeListener(event); @@ -143,7 +159,7 @@ public class PolarisPropertiesSourceAutoRefresherTest { @Test public void testConfigFileGroupChanged() throws Exception { PolarisRefreshAffectedContextRefresher refresher = new PolarisRefreshAffectedContextRefresher( - polarisConfigProperties, springValueRegistry, placeholderHelper, configFileService, contextRefresher); + polarisConfigProperties, springValueRegistry, placeholderHelper, configFileService, contextRefresher, sdkContext); ConfigurableApplicationContext applicationContext = mock(ConfigurableApplicationContext.class); ConfigurableListableBeanFactory beanFactory = mock(ConfigurableListableBeanFactory.class); TypeConverter typeConverter = mock(TypeConverter.class); @@ -189,6 +205,8 @@ public class PolarisPropertiesSourceAutoRefresherTest { when(configFileService.getConfigPropertiesFile(testNamespace, testFileGroup, "file2.properties")) .thenReturn(file2); + when(sdkContext.getExtensions()).thenReturn(extensions); + when(extensions.getValueContext()).thenReturn(valueContext); revisableConfigFileGroup.updateConfigFileList(Arrays.asList(file, file2), "v2"); Thread.sleep(5000); @@ -206,7 +224,7 @@ public class PolarisPropertiesSourceAutoRefresherTest { changeInfos.put("k1", changeInfo); changeInfos.put("k3.1", changeInfo2); changeInfos.put("k4", changeInfo3); - ConfigKVFileChangeEvent event = new ConfigKVFileChangeEvent(changeInfos); + ConfigKVFileChangeEvent event = new ConfigKVFileChangeEvent(changeInfos, null); file2.fireChangeListener(event); Thread.sleep(5000); diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisRefreshEntireContextRefresherTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisRefreshEntireContextRefresherTest.java index dc90f2e37..09a341146 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisRefreshEntireContextRefresherTest.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisRefreshEntireContextRefresherTest.java @@ -25,6 +25,7 @@ import java.util.Set; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; import com.tencent.cloud.polaris.config.spring.property.SpringValueRegistry; +import com.tencent.polaris.client.api.SDKContext; import com.tencent.polaris.configuration.api.core.ConfigFileService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -70,6 +71,9 @@ public class PolarisRefreshEntireContextRefresherTest { private PolarisRefreshEntireContextRefresher refresher; + @Mock + private SDKContext context; + @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); @@ -77,7 +81,8 @@ public class PolarisRefreshEntireContextRefresherTest { polarisConfigProperties, springValueRegistry, configFileService, - contextRefresher + contextRefresher, + context ); refresher.setApplicationContext(applicationContext); } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java index 8e18a0a2b..1e0b6a1ff 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisAutoServiceRegistration.java @@ -21,9 +21,8 @@ import java.time.LocalDateTime; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; import com.tencent.polaris.api.plugin.compose.Extensions; +import com.tencent.polaris.api.plugin.event.EventConstants; import com.tencent.polaris.api.plugin.event.FlowEvent; -import com.tencent.polaris.api.plugin.event.FlowEventConstants; -import com.tencent.polaris.api.pojo.ServiceEventKey; import com.tencent.polaris.assembly.api.AssemblyAPI; import com.tencent.polaris.client.flow.BaseFlow; import org.slf4j.Logger; @@ -96,8 +95,8 @@ public class PolarisAutoServiceRegistration extends AbstractAutoServiceRegistrat && this.registration.getPolarisContext().getExtensions() != null) { Extensions extensions = this.registration.getPolarisContext().getExtensions(); FlowEvent.Builder flowEventBuilder = new FlowEvent.Builder() - .withEventType(ServiceEventKey.EventType.INSTANCE) - .withEventName(FlowEventConstants.EventName.InstanceThreadEnd) + .withEventType(EventConstants.EventType.INSTANCE) + .withEventName(EventConstants.EventName.InstanceThreadEnd) .withTimestamp(LocalDateTime.now()) .withClientId(extensions.getValueContext().getClientId()) .withClientIp(extensions.getValueContext().getHost()) diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index e27009994..c2bb2f0b5 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -74,7 +74,7 @@ 2.0.1.0-2021.0.9-RC2 - 2.0.1.0-RC1 + 2.0.1.0-SNAPSHOT 1.78.1