init
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
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">
|
||||
<parent>
|
||||
<artifactId>sentinel-extension</artifactId>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<version>1.8.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>sentinel-datasource-apollo</artifactId>
|
||||
|
||||
<properties>
|
||||
<apollo.version>1.5.0</apollo.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-datasource-extension</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.ctrip.framework.apollo</groupId>
|
||||
<artifactId>apollo-client</artifactId>
|
||||
<version>${apollo.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.alibaba.csp.sentinel.datasource.apollo;
|
||||
|
||||
import com.alibaba.csp.sentinel.datasource.AbstractDataSource;
|
||||
import com.alibaba.csp.sentinel.datasource.Converter;
|
||||
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||
|
||||
import com.ctrip.framework.apollo.Config;
|
||||
import com.ctrip.framework.apollo.ConfigChangeListener;
|
||||
import com.ctrip.framework.apollo.ConfigService;
|
||||
import com.ctrip.framework.apollo.model.ConfigChange;
|
||||
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* A read-only {@code DataSource} with <a href="http://github.com/ctripcorp/apollo">Apollo</a> as its configuration
|
||||
* source.
|
||||
* <br />
|
||||
* When the rule is changed in Apollo, it will take effect in real time.
|
||||
*
|
||||
* @author Jason Song
|
||||
* @author Haojun Ren
|
||||
*/
|
||||
public class ApolloDataSource<T> extends AbstractDataSource<String, T> {
|
||||
|
||||
private final Config config;
|
||||
private final String ruleKey;
|
||||
private final String defaultRuleValue;
|
||||
|
||||
private ConfigChangeListener configChangeListener;
|
||||
|
||||
/**
|
||||
* Constructs the Apollo data source
|
||||
*
|
||||
* @param namespaceName the namespace name in Apollo, should not be null or empty
|
||||
* @param ruleKey the rule key in the namespace, should not be null or empty
|
||||
* @param defaultRuleValue the default rule value when the ruleKey is not found or any error
|
||||
* occurred
|
||||
* @param parser the parser to transform string configuration to actual flow rules
|
||||
*/
|
||||
public ApolloDataSource(String namespaceName, String ruleKey, String defaultRuleValue,
|
||||
Converter<String, T> parser) {
|
||||
super(parser);
|
||||
|
||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespaceName), "Namespace name could not be null or empty");
|
||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(ruleKey), "RuleKey could not be null or empty!");
|
||||
|
||||
this.ruleKey = ruleKey;
|
||||
this.defaultRuleValue = defaultRuleValue;
|
||||
|
||||
this.config = ConfigService.getConfig(namespaceName);
|
||||
|
||||
initialize();
|
||||
|
||||
RecordLog.info("Initialized rule for namespace: {}, rule key: {}", namespaceName, ruleKey);
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
initializeConfigChangeListener();
|
||||
loadAndUpdateRules();
|
||||
}
|
||||
|
||||
private void loadAndUpdateRules() {
|
||||
try {
|
||||
T newValue = loadConfig();
|
||||
if (newValue == null) {
|
||||
RecordLog.warn("[ApolloDataSource] WARN: rule config is null, you may have to check your data source");
|
||||
}
|
||||
getProperty().updateValue(newValue);
|
||||
} catch (Throwable ex) {
|
||||
RecordLog.warn("[ApolloDataSource] Error when loading rule config", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeConfigChangeListener() {
|
||||
configChangeListener = new ConfigChangeListener() {
|
||||
@Override
|
||||
public void onChange(ConfigChangeEvent changeEvent) {
|
||||
ConfigChange change = changeEvent.getChange(ruleKey);
|
||||
//change is never null because the listener will only notify for this key
|
||||
if (change != null) {
|
||||
RecordLog.info("[ApolloDataSource] Received config changes: {}", change);
|
||||
}
|
||||
loadAndUpdateRules();
|
||||
}
|
||||
};
|
||||
config.addChangeListener(configChangeListener, Sets.newHashSet(ruleKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readSource() throws Exception {
|
||||
return config.getProperty(ruleKey, defaultRuleValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
config.removeChangeListener(configChangeListener);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user