diff --git a/sentinel-extension/sentinel-datasource-apollo/src/main/java/com/alibaba/csp/sentinel/datasource/apollo/ApolloDataSource.java b/sentinel-extension/sentinel-datasource-apollo/src/main/java/com/alibaba/csp/sentinel/datasource/apollo/ApolloDataSource.java
index 51561f1d..9a7898de 100644
--- a/sentinel-extension/sentinel-datasource-apollo/src/main/java/com/alibaba/csp/sentinel/datasource/apollo/ApolloDataSource.java
+++ b/sentinel-extension/sentinel-datasource-apollo/src/main/java/com/alibaba/csp/sentinel/datasource/apollo/ApolloDataSource.java
@@ -1,9 +1,9 @@
package com.alibaba.csp.sentinel.datasource.apollo;
import com.alibaba.csp.sentinel.datasource.AbstractDataSource;
-import com.alibaba.csp.sentinel.datasource.ConfigParser;
-import com.alibaba.csp.sentinel.datasource.DataSource;
+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;
@@ -14,7 +14,8 @@ import com.google.common.base.Strings;
import com.google.common.collect.Sets;
/**
- * A {@link DataSource} with Apollo as its configuration source.
+ * A read-only {@code DataSource} with Apollo as its configuration
+ * source.
*
* When the rule is changed in Apollo, it will take effect in real time.
*
@@ -22,73 +23,75 @@ import com.google.common.collect.Sets;
*/
public class ApolloDataSource extends AbstractDataSource {
- private final Config config;
- private final String flowRulesKey;
- private final String defaultFlowRuleValue;
-
- /**
- * Constructs the Apollo data source
- *
- * @param namespaceName the namespace name in Apollo, should not be null or empty
- * @param flowRulesKey the flow rules key in the namespace, should not be null or empty
- * @param defaultFlowRuleValue the default flow rules value when the flow rules key is not found or any error occurred
- * @param parser the parser to transform string configuration to actual flow rules
- */
- public ApolloDataSource(String namespaceName, String flowRulesKey, String defaultFlowRuleValue,
- ConfigParser parser) {
- super(parser);
+ private final Config config;
+ private final String flowRulesKey;
+ private final String defaultFlowRuleValue;
- Preconditions.checkArgument(!Strings.isNullOrEmpty(namespaceName), "Namespace name could not be null or empty");
- Preconditions.checkArgument(!Strings.isNullOrEmpty(flowRulesKey), "FlowRuleKey could not be null or empty!");
+ /**
+ * Constructs the Apollo data source
+ *
+ * @param namespaceName the namespace name in Apollo, should not be null or empty
+ * @param flowRulesKey the flow rules key in the namespace, should not be null or empty
+ * @param defaultFlowRuleValue the default flow rules value when the flow rules key is not found or any error
+ * occurred
+ * @param parser the parser to transform string configuration to actual flow rules
+ */
+ public ApolloDataSource(String namespaceName, String flowRulesKey, String defaultFlowRuleValue,
+ Converter parser) {
+ super(parser);
- this.flowRulesKey = flowRulesKey;
- this.defaultFlowRuleValue = defaultFlowRuleValue;
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(namespaceName), "Namespace name could not be null or empty");
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(flowRulesKey), "FlowRuleKey could not be null or empty!");
- this.config = ConfigService.getConfig(namespaceName);
+ this.flowRulesKey = flowRulesKey;
+ this.defaultFlowRuleValue = defaultFlowRuleValue;
- initialize();
+ this.config = ConfigService.getConfig(namespaceName);
- RecordLog.info(String.format("Initialized rule for namespace: %s, flow rules key: %s", namespaceName, flowRulesKey));
- }
+ initialize();
- private void initialize() {
- initializeConfigChangeListener();
- loadAndUpdateRules();
- }
+ RecordLog.info(String.format("Initialized rule for namespace: %s, flow rules key: %s",
+ namespaceName, flowRulesKey));
+ }
- 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 initialize() {
+ initializeConfigChangeListener();
+ loadAndUpdateRules();
}
- }
- private void initializeConfigChangeListener() {
- config.addChangeListener(new ConfigChangeListener() {
- @Override
- public void onChange(ConfigChangeEvent changeEvent) {
- ConfigChange change = changeEvent.getChange(flowRulesKey);
- //change is never null because the listener will only notify for this key
- if (change != null) {
- RecordLog.info("[ApolloDataSource] Received config changes: " + change.toString());
+ 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);
}
- loadAndUpdateRules();
- }
- }, Sets.newHashSet(flowRulesKey));
- }
+ }
- @Override
- public String readSource() throws Exception {
- return config.getProperty(flowRulesKey, defaultFlowRuleValue);
- }
+ private void initializeConfigChangeListener() {
+ config.addChangeListener(new ConfigChangeListener() {
+ @Override
+ public void onChange(ConfigChangeEvent changeEvent) {
+ ConfigChange change = changeEvent.getChange(flowRulesKey);
+ //change is never null because the listener will only notify for this key
+ if (change != null) {
+ RecordLog.info("[ApolloDataSource] Received config changes: " + change.toString());
+ }
+ loadAndUpdateRules();
+ }
+ }, Sets.newHashSet(flowRulesKey));
+ }
- @Override
- public void close() throws Exception {
- // nothing to destroy
- }
+ @Override
+ public String readSource() throws Exception {
+ return config.getProperty(flowRulesKey, defaultFlowRuleValue);
+ }
+
+ @Override
+ public void close() throws Exception {
+ // nothing to destroy
+ }
}
diff --git a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/AbstractDataSource.java b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/AbstractDataSource.java
index ec5b66d9..ca06b514 100755
--- a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/AbstractDataSource.java
+++ b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/AbstractDataSource.java
@@ -18,12 +18,20 @@ package com.alibaba.csp.sentinel.datasource;
import com.alibaba.csp.sentinel.property.DynamicSentinelProperty;
import com.alibaba.csp.sentinel.property.SentinelProperty;
-public abstract class AbstractDataSource implements DataSource {
+/**
+ * The abstract readable data source provides basic functionality for loading and parsing config.
+ *
+ * @param source data type
+ * @param target data type
+ * @author Carpenter Lee
+ * @author Eric Zhao
+ */
+public abstract class AbstractDataSource implements ReadableDataSource {
- protected final ConfigParser parser;
+ protected final Converter parser;
protected final SentinelProperty property;
- public AbstractDataSource(ConfigParser parser) {
+ public AbstractDataSource(Converter parser) {
if (parser == null) {
throw new IllegalArgumentException("parser can't be null");
}
@@ -33,13 +41,11 @@ public abstract class AbstractDataSource implements DataSource {
@Override
public T loadConfig() throws Exception {
- S readValue = readSource();
- T value = parser.parse(readValue);
- return value;
+ return loadConfig(readSource());
}
public T loadConfig(S conf) throws Exception {
- T value = parser.parse(conf);
+ T value = parser.convert(conf);
return value;
}
@@ -47,10 +53,4 @@ public abstract class AbstractDataSource implements DataSource {
public SentinelProperty getProperty() {
return property;
}
-
- @Override
- public void writeDataSource(T values) throws Exception {
- throw new UnsupportedOperationException();
- }
-
}
diff --git a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/AutoRefreshDataSource.java b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/AutoRefreshDataSource.java
index 645c4180..ff854627 100755
--- a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/AutoRefreshDataSource.java
+++ b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/AutoRefreshDataSource.java
@@ -23,7 +23,7 @@ import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory;
import com.alibaba.csp.sentinel.log.RecordLog;
/**
- * A {@link DataSource} automatically fetches the backend data.
+ * A {@link ReadableDataSource} automatically fetches the backend data.
*
* @param source data type
* @param target data type
@@ -34,12 +34,12 @@ public abstract class AutoRefreshDataSource extends AbstractDataSource configParser) {
+ public AutoRefreshDataSource(Converter configParser) {
super(configParser);
startTimerService();
}
- public AutoRefreshDataSource(ConfigParser configParser, final long recommendRefreshMs) {
+ public AutoRefreshDataSource(Converter configParser, final long recommendRefreshMs) {
super(configParser);
if (recommendRefreshMs <= 0) {
throw new IllegalArgumentException("recommendRefreshMs must > 0, but " + recommendRefreshMs + " get");
@@ -72,5 +72,4 @@ public abstract class AutoRefreshDataSource extends AbstractDataSource {
+public interface Converter {
+
/**
- * Parse {@code source} to the target format.
+ * Convert {@code source} to the target type.
*
- * @param source the source.
- * @return the target.
+ * @param source the source object
+ * @return the target object
*/
- T parse(S source);
+ T convert(S source);
}
diff --git a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/EmptyDataSource.java b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/EmptyDataSource.java
index 574e6692..7e185f14 100755
--- a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/EmptyDataSource.java
+++ b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/EmptyDataSource.java
@@ -19,18 +19,18 @@ import com.alibaba.csp.sentinel.property.NoOpSentinelProperty;
import com.alibaba.csp.sentinel.property.SentinelProperty;
/**
- * A {@link DataSource} based on nothing. {@link EmptyDataSource#getProperty()} will always return the same cached
+ * A {@link ReadableDataSource} based on nothing. {@link EmptyDataSource#getProperty()} will always return the same cached
* {@link SentinelProperty} that doing nothing.
*
- * This class is used when we want to use default settings instead of configs from the {@link DataSource}
+ * This class is used when we want to use default settings instead of configs from the {@link ReadableDataSource}.
*
* @author leyou
*/
-public class EmptyDataSource implements DataSource