Publish spring event named ConfigChangeSpringEvent when the configuration is changed. (#647)

* public config change spring event

* update changelog

* Update ConfigChangeSpringEventTest.java

add license for ConfigChangeSpringEventTest

Co-authored-by: Haotian Zhang <928016560@qq.com>
pull/656/head
DerekYRC 2 years ago committed by GitHub
parent 3f21289042
commit e71d845b93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -21,3 +21,4 @@
- [Feature: support read config file from local file system](https://github.com/Tencent/spring-cloud-tencent/pull/640)
- [fix:optimize expression parser V1.](https://github.com/Tencent/spring-cloud-tencent/pull/642)
- [Optimize: add transfer metadata unit test.](https://github.com/Tencent/spring-cloud-tencent/pull/646)
- [feat: publish spring event named ConfigChangeSpringEvent when the configuration is changed](https://github.com/Tencent/spring-cloud-tencent/pull/647)

@ -23,11 +23,14 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import com.google.common.collect.Maps;
import com.tencent.cloud.polaris.config.spring.event.ConfigChangeSpringEvent;
import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
@ -44,10 +47,12 @@ import static com.tencent.cloud.polaris.config.listener.PolarisConfigListenerCon
*
* @author <a href="mailto:iskp.me@gmail.com">Elve.Xu</a> 2022-06-08
*/
public final class PolarisConfigChangeEventListener implements ApplicationListener<ApplicationEvent> {
public final class PolarisConfigChangeEventListener implements ApplicationListener<ApplicationEvent>, ApplicationEventPublisherAware {
private static final AtomicBoolean started = new AtomicBoolean();
private ApplicationEventPublisher eventPublisher;
/**
* Handle an application event.
*
@ -72,6 +77,8 @@ public final class PolarisConfigChangeEventListener implements ApplicationListen
ConfigurableEnvironment environment = context.getEnvironment();
Map<String, Object> ret = loadEnvironmentProperties(environment);
Map<String, ConfigPropertyChangeInfo> changes = merge(ret);
ConfigChangeSpringEvent configChangeSpringEvent = new ConfigChangeSpringEvent(Maps.newHashMap(changes));
eventPublisher.publishEvent(configChangeSpringEvent);
fireConfigChange(changes.keySet(), Maps.newHashMap(changes));
changes.clear();
}
@ -106,4 +113,9 @@ public final class PolarisConfigChangeEventListener implements ApplicationListen
});
return ret;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
}

@ -0,0 +1,70 @@
/*
* 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.spring.event;
import java.util.Map;
import java.util.Set;
import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
import org.springframework.context.ApplicationEvent;
/**
* A spring change event when config is changed.
*
* @author Derek Yi 2022-10-16
*/
public class ConfigChangeSpringEvent extends ApplicationEvent {
/**
* @param source all changed keys map.
*/
public ConfigChangeSpringEvent(Map<String, ConfigPropertyChangeInfo> source) {
super(source);
}
/**
* Get the changed keys.
* @return the list of the keys
*/
public Set<String> changedKeys() {
return changeMap().keySet();
}
/**
* Get a specific change instance for the key specified.
* @param key the changed key
* @return the change instance
*/
public ConfigPropertyChangeInfo getChange(String key) {
return changeMap().get(key);
}
/**
* Check whether the specified key is changed .
* @param key the key
* @return true if the key is changed, false otherwise.
*/
public boolean isChanged(String key) {
return changeMap().containsKey(key);
}
private Map<String, ConfigPropertyChangeInfo> changeMap() {
return (Map<String, ConfigPropertyChangeInfo>) getSource();
}
}

@ -0,0 +1,80 @@
/*
* 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.spring.event;
import java.util.HashMap;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import com.tencent.polaris.configuration.api.core.ChangeType;
import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
/**
* Test for {@link ConfigChangeSpringEvent}.
*
* @author derek.yi 2022-10-16
*/
public class ConfigChangeSpringEventTest {
private static CountDownLatch countDownLatch = new CountDownLatch(1);
private static AtomicInteger receiveEventTimes = new AtomicInteger();
@Test
public void testPublishConfigChangeSpringEvent() {
ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ConfigChangeSpringEventListener.class));
contextRunner.run(context -> {
HashMap<String, ConfigPropertyChangeInfo> changeMap = new HashMap<>();
changeMap.put("key", new ConfigPropertyChangeInfo("key", null, "value", ChangeType.ADDED));
context.publishEvent(new ConfigChangeSpringEvent(changeMap));
countDownLatch.await(5, TimeUnit.SECONDS);
Assert.assertEquals(1, receiveEventTimes.get());
});
}
@Configuration
static class ConfigChangeSpringEventListener implements ApplicationListener<ConfigChangeSpringEvent> {
@Override
public void onApplicationEvent(ConfigChangeSpringEvent event) {
Set<String> changedKeys = event.changedKeys();
Assert.assertEquals(1, changedKeys.size());
Assert.assertTrue(event.isChanged("key"));
ConfigPropertyChangeInfo changeInfo = event.getChange("key");
Assert.assertNotNull(changeInfo);
Assert.assertEquals("key", changeInfo.getPropertyName());
Assert.assertEquals("value", changeInfo.getNewValue());
Assert.assertEquals(ChangeType.ADDED, changeInfo.getChangeType());
receiveEventTimes.incrementAndGet();
countDownLatch.countDown();
}
}
}
Loading…
Cancel
Save