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