Add config change listener feature support (#299)
Co-authored-by: lepdou <ledouzhang@tencent.com>pull/301/head
parent
db45a57f18
commit
eb72d49506
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.listener;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
|
||||
|
||||
/**
|
||||
* A change event when config is changed .
|
||||
*
|
||||
* @author <a href="mailto:iskp.me@gmail.com">Palmer Xu</a> 2022-06-07
|
||||
*/
|
||||
public final class ConfigChangeEvent {
|
||||
|
||||
/**
|
||||
* all changes keys map.
|
||||
*/
|
||||
private final Map<String, ConfigPropertyChangeInfo> changes;
|
||||
|
||||
/**
|
||||
* all interested changed keys.
|
||||
*/
|
||||
private final Set<String> interestedChangedKeys;
|
||||
|
||||
/**
|
||||
* Config Change Event Constructor.
|
||||
* @param changes all changes keys map
|
||||
* @param interestedChangedKeys all interested changed keys
|
||||
*/
|
||||
public ConfigChangeEvent(Map<String, ConfigPropertyChangeInfo> changes, Set<String> interestedChangedKeys) {
|
||||
this.changes = changes;
|
||||
this.interestedChangedKeys = interestedChangedKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the keys changed.
|
||||
* @return the list of the keys
|
||||
*/
|
||||
public Set<String> changedKeys() {
|
||||
return changes.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 changes.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 changes.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe subclass override this method.
|
||||
*
|
||||
* @return interested and changed keys
|
||||
*/
|
||||
public Set<String> interestedChangedKeys() {
|
||||
return interestedChangedKeys;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.listener;
|
||||
|
||||
/**
|
||||
* Configuring the change listener interface.
|
||||
*
|
||||
* @author Palmer Xu 2022-05-31
|
||||
*/
|
||||
public interface ConfigChangeListener {
|
||||
|
||||
/**
|
||||
* Invoked when there is any config change for the namespace.
|
||||
*
|
||||
* @param changeEvent the event for this change
|
||||
*/
|
||||
void onChange(ConfigChangeEvent changeEvent);
|
||||
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.listener;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
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.ApplicationListener;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import static com.tencent.cloud.polaris.config.listener.PolarisConfigListenerContext.fireConfigChange;
|
||||
import static com.tencent.cloud.polaris.config.listener.PolarisConfigListenerContext.initialize;
|
||||
import static com.tencent.cloud.polaris.config.listener.PolarisConfigListenerContext.merge;
|
||||
|
||||
/**
|
||||
* Polaris Config Change Event Listener .
|
||||
*
|
||||
* @author <a href="mailto:iskp.me@gmail.com">Elve.Xu</a> 2022-06-08
|
||||
*/
|
||||
public final class PolarisConfigChangeEventListener implements ApplicationListener<ApplicationEvent> {
|
||||
|
||||
private static final AtomicBoolean started = new AtomicBoolean();
|
||||
|
||||
/**
|
||||
* Handle an application event.
|
||||
*
|
||||
* @param event the event to respond to
|
||||
*/
|
||||
@Override
|
||||
public void onApplicationEvent(@NonNull ApplicationEvent event) {
|
||||
|
||||
// Initialize application all environment properties .
|
||||
if (event instanceof ApplicationStartedEvent && started.compareAndSet(false, true)) {
|
||||
ApplicationStartedEvent applicationStartedEvent = (ApplicationStartedEvent) event;
|
||||
ConfigurableEnvironment environment = applicationStartedEvent.getApplicationContext().getEnvironment();
|
||||
Map<String, Object> ret = loadEnvironmentProperties(environment);
|
||||
if (!ret.isEmpty()) {
|
||||
initialize(ret);
|
||||
}
|
||||
}
|
||||
|
||||
// Process Environment Change Event .
|
||||
if (event instanceof EnvironmentChangeEvent) {
|
||||
EnvironmentChangeEvent environmentChangeEvent = (EnvironmentChangeEvent) event;
|
||||
ConfigurableApplicationContext context = (ConfigurableApplicationContext) environmentChangeEvent.getSource();
|
||||
ConfigurableEnvironment environment = context.getEnvironment();
|
||||
Map<String, Object> ret = loadEnvironmentProperties(environment);
|
||||
Map<String, ConfigPropertyChangeInfo> changes = merge(ret);
|
||||
fireConfigChange(changes.keySet(), Maps.newHashMap(changes));
|
||||
changes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try load all application environment config properties .
|
||||
* @param environment application environment instance of {@link Environment}
|
||||
* @return properties
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> loadEnvironmentProperties(ConfigurableEnvironment environment) {
|
||||
Map<String, Object> ret = Maps.newHashMap();
|
||||
MutablePropertySources sources = environment.getPropertySources();
|
||||
sources.iterator().forEachRemaining(propertySource -> {
|
||||
Object o = propertySource.getSource();
|
||||
if (o instanceof Map) {
|
||||
for (Map.Entry<String, Object> entry : ((Map<String, Object>) o).entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = environment.getProperty(key);
|
||||
ret.put(key, value);
|
||||
}
|
||||
}
|
||||
else if (o instanceof Collection) {
|
||||
int count = 0;
|
||||
Collection<Object> collection = (Collection<Object>) o;
|
||||
for (Object object : collection) {
|
||||
String key = "[" + (count++) + "]";
|
||||
ret.put(key, object);
|
||||
}
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.example;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.tencent.cloud.polaris.config.annotation.PolarisConfigKVFileChangeListener;
|
||||
import com.tencent.cloud.polaris.config.listener.ConfigChangeEvent;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Custom Config Listener Example .
|
||||
*
|
||||
* @author Palmer Xu 2022-06-06
|
||||
*/
|
||||
@Component
|
||||
public final class PersonConfigChangeListener {
|
||||
|
||||
/**
|
||||
* PolarisConfigKVFileChangeListener Example .
|
||||
* @param event instance of {@link ConfigChangeEvent}
|
||||
*/
|
||||
@PolarisConfigKVFileChangeListener(interestedKeyPrefixes = "teacher")
|
||||
public void onChange(ConfigChangeEvent event) {
|
||||
Set<String> changedKeys = event.changedKeys();
|
||||
|
||||
for (String changedKey : changedKeys) {
|
||||
System.out.printf("%s = %s \n", changedKey, event.getChange(changedKey));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue