publish spring event named ConfigChangeSpringEvent when the configuration is changed (#651)

pull/661/head
DerekYRC 2 years ago committed by GitHub
parent 08a16d81d4
commit a0048d1f29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -12,3 +12,4 @@
- [support spring-retry router](https://github.com/Tencent/spring-cloud-tencent/pull/631) - [support spring-retry router](https://github.com/Tencent/spring-cloud-tencent/pull/631)
- [feat:Transfer http headers specified by environment variables](https://github.com/Tencent/spring-cloud-tencent/pull/638) - [feat:Transfer http headers specified by environment variables](https://github.com/Tencent/spring-cloud-tencent/pull/638)
- [feat:support read config file from local file system.](https://github.com/Tencent/spring-cloud-tencent/pull/649) - [feat:support read config file from local file system.](https://github.com/Tencent/spring-cloud-tencent/pull/649)
- [feat: publish spring event named ConfigChangeSpringEvent when the configuration is changed](https://github.com/Tencent/spring-cloud-tencent/pull/651)

@ -23,11 +23,14 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.tencent.cloud.polaris.config.spring.event.ConfigChangeSpringEvent;
import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo; import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment; 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 * @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 static final AtomicBoolean started = new AtomicBoolean();
private ApplicationEventPublisher eventPublisher;
/** /**
* Handle an application event. * Handle an application event.
* *
@ -73,6 +78,8 @@ public final class PolarisConfigChangeEventListener implements ApplicationListen
ConfigurableEnvironment environment = context.getEnvironment(); ConfigurableEnvironment environment = context.getEnvironment();
Map<String, Object> ret = loadEnvironmentProperties(environment); Map<String, Object> ret = loadEnvironmentProperties(environment);
Map<String, ConfigPropertyChangeInfo> changes = merge(ret); Map<String, ConfigPropertyChangeInfo> changes = merge(ret);
ConfigChangeSpringEvent configChangeSpringEvent = new ConfigChangeSpringEvent(Maps.newHashMap(changes));
eventPublisher.publishEvent(configChangeSpringEvent);
fireConfigChange(changes.keySet(), Maps.newHashMap(changes)); fireConfigChange(changes.keySet(), Maps.newHashMap(changes));
changes.clear(); changes.clear();
} }
@ -107,4 +114,9 @@ public final class PolarisConfigChangeEventListener implements ApplicationListen
}); });
return ret; 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