From 0060e8042a65031495540bf5b28041db0000916b Mon Sep 17 00:00:00 2001 From: Eric Zhao Date: Mon, 3 Sep 2018 19:20:02 +0800 Subject: [PATCH] Refactor Sentinel data source hierarchy - Spilt DataSource into two types: ReadableDataSource and WritableDataSource - The AbstractDataSource now is read-only - Refactor the file data source for writable implementation - Rename: ConfigParser -> Converter (represents both encoder `T -> S` and decoder `S -> T`) - Some other refinement Signed-off-by: Eric Zhao --- .../datasource/apollo/ApolloDataSource.java | 123 +++++++++--------- .../datasource/AbstractDataSource.java | 26 ++-- .../datasource/AutoRefreshDataSource.java | 7 +- .../{ConfigParser.java => Converter.java} | 14 +- .../sentinel/datasource/EmptyDataSource.java | 18 +-- .../datasource/FileRefreshableDataSource.java | 50 +++---- ...ataSource.java => ReadableDataSource.java} | 19 +-- .../datasource/WritableDataSource.java | 33 +++++ .../sentinel-datasource-nacos/README.md | 2 +- .../datasource/nacos/NacosDataSource.java | 17 ++- .../sentinel-datasource-zookeeper/README.md | 2 +- .../zookeeper/ZookeeperDataSource.java | 16 +-- .../zookeeper/ZookeeperDataSourceTest.java | 10 +- 13 files changed, 183 insertions(+), 154 deletions(-) rename sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/{ConfigParser.java => Converter.java} (72%) rename sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/{DataSource.java => ReadableDataSource.java} (79%) create mode 100644 sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/WritableDataSource.java 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 { +public final class EmptyDataSource implements ReadableDataSource { - public static final DataSource EMPTY_DATASOURCE = new EmptyDataSource(); + public static final ReadableDataSource EMPTY_DATASOURCE = new EmptyDataSource(); - private static final SentinelProperty property = new NoOpSentinelProperty(); + private static final SentinelProperty PROPERTY = new NoOpSentinelProperty(); private EmptyDataSource() { } @@ -46,15 +46,9 @@ public class EmptyDataSource implements DataSource { @Override public SentinelProperty getProperty() { - return property; + return PROPERTY; } @Override public void close() throws Exception { } - - @Override - public void writeDataSource(Object config) throws Exception { - throw new UnsupportedOperationException(); - } - } diff --git a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/FileRefreshableDataSource.java b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/FileRefreshableDataSource.java index 6d3ea7da..7183dd75 100755 --- a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/FileRefreshableDataSource.java +++ b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/FileRefreshableDataSource.java @@ -25,16 +25,17 @@ import com.alibaba.csp.sentinel.log.RecordLog; /** *

- * A {@link DataSource} based on file. This class will automatically fetches the backend file every 3 seconds. + * A {@link WritableDataSource} based on file. This class will automatically fetches the backend file every refresh period. *

*

- * Limitations: default read buffer size is 1MB, if file size is greater than buffer size, exceeding bytes will - * be ignored. Default charset is UTF8. + * Limitations: Default read buffer size is 1 MB. If file size is greater than buffer size, exceeding bytes will + * be ignored. Default charset is UTF-8. *

* * @author Carpenter Lee + * @author Eric Zhao */ -public class FileRefreshableDataSource extends AutoRefreshDataSource { +public class FileRefreshableDataSource extends AutoRefreshDataSource implements WritableDataSource { private static final int MAX_SIZE = 1024 * 1024 * 4; private static final long DEFAULT_REFRESH_MS = 3000; @@ -42,37 +43,38 @@ public class FileRefreshableDataSource extends AutoRefreshDataSource configEncoder; /** - * Create a file based {@link DataSource} whose read buffer size is 1MB, charset is UTF8, + * Create a file based {@link ReadableDataSource} whose read buffer size is 1MB, charset is UTF8, * and read interval is 3 seconds. * - * @param file the file to read. - * @param configParser the config parser. + * @param file the file to read + * @param configParser the config decoder (parser) */ - public FileRefreshableDataSource(File file, ConfigParser configParser) throws FileNotFoundException { - this(file, configParser, DEFAULT_REFRESH_MS, DEFAULT_BUF_SIZE, DEFAULT_CHAR_SET); + public FileRefreshableDataSource(File file, Converter configParser, Converter configEncoder) throws FileNotFoundException { + this(file, configParser, configEncoder, DEFAULT_REFRESH_MS, DEFAULT_BUF_SIZE, DEFAULT_CHAR_SET); } - public FileRefreshableDataSource(String fileName, ConfigParser configParser) + public FileRefreshableDataSource(String fileName, Converter configParser, Converter configEncoder) throws FileNotFoundException { - this(new File(fileName), configParser, DEFAULT_REFRESH_MS, DEFAULT_BUF_SIZE, DEFAULT_CHAR_SET); - //System.out.println(file.getAbsoluteFile()); + this(new File(fileName), configParser, configEncoder, DEFAULT_REFRESH_MS, DEFAULT_BUF_SIZE, DEFAULT_CHAR_SET); } - public FileRefreshableDataSource(File file, ConfigParser configParser, int bufSize) + public FileRefreshableDataSource(File file, Converter configParser, Converter configEncoder, int bufSize) throws FileNotFoundException { - this(file, configParser, DEFAULT_REFRESH_MS, bufSize, DEFAULT_CHAR_SET); + this(file, configParser, configEncoder, DEFAULT_REFRESH_MS, bufSize, DEFAULT_CHAR_SET); } - public FileRefreshableDataSource(File file, ConfigParser configParser, Charset charset) + public FileRefreshableDataSource(File file, Converter configParser, Converter configEncoder, Charset charset) throws FileNotFoundException { - this(file, configParser, DEFAULT_REFRESH_MS, DEFAULT_BUF_SIZE, charset); + this(file, configParser, configEncoder, DEFAULT_REFRESH_MS, DEFAULT_BUF_SIZE, charset); } - public FileRefreshableDataSource(File file, ConfigParser configParser, long recommendRefreshMs, + public FileRefreshableDataSource(File file, Converter configParser, Converter configEncoder, long recommendRefreshMs, int bufSize, Charset charset) throws FileNotFoundException { super(configParser, recommendRefreshMs); if (bufSize <= 0 || bufSize > MAX_SIZE) { @@ -84,9 +86,13 @@ public class FileRefreshableDataSource extends AutoRefreshDataSource extends AutoRefreshDataSource buf.length) { - throw new RuntimeException(file.getAbsolutePath() + " file size=" + channel.size() + throw new IllegalStateException(file.getAbsolutePath() + " file size=" + channel.size() + ", is bigger than bufSize=" + buf.length + ". Can't read"); } int len = inputStream.read(buf); @@ -128,7 +134,7 @@ public class FileRefreshableDataSource extends AutoRefreshDataSource source data type * @param target data type * @author leyou + * @author Eric Zhao */ -public interface DataSource { +public interface ReadableDataSource { /** * Load data data source as the target type. * * @return the target data. - * @throws Exception + * @throws Exception IO or other error occurs */ T loadConfig() throws Exception; @@ -38,7 +39,7 @@ public interface DataSource { * Read original data from the data source. * * @return the original data. - * @throws Exception + * @throws Exception IO or other error occurs */ S readSource() throws Exception; @@ -49,18 +50,10 @@ public interface DataSource { */ SentinelProperty getProperty(); - /** - * Write the {@code values} to the data source. - * - * @param values - * @throws Exception - */ - void writeDataSource(T values) throws Exception; - /** * Close the data source. * - * @throws Exception + * @throws Exception IO or other error occurs */ void close() throws Exception; } diff --git a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/WritableDataSource.java b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/WritableDataSource.java new file mode 100644 index 00000000..f63dd21d --- /dev/null +++ b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/WritableDataSource.java @@ -0,0 +1,33 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.alibaba.csp.sentinel.datasource; + +/** + * Interface of writable data source support. + * + * @author Eric Zhao + * @since 0.2.0 + */ +public interface WritableDataSource { + + /** + * Write the {@code value} to the data source. + * + * @param value value to write + * @throws Exception IO or other error occurs + */ + void write(T value) throws Exception; +} diff --git a/sentinel-extension/sentinel-datasource-nacos/README.md b/sentinel-extension/sentinel-datasource-nacos/README.md index 6b16fe28..3496e644 100644 --- a/sentinel-extension/sentinel-datasource-nacos/README.md +++ b/sentinel-extension/sentinel-datasource-nacos/README.md @@ -19,7 +19,7 @@ For instance: ```java // remoteAddress is the address of Nacos // groupId and dataId are concepts of Nacos -DataSource> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId, +ReadableDataSource> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId, source -> JSON.parseObject(source, new TypeReference>() {})); FlowRuleManager.register2Property(flowRuleDataSource.getProperty()); ``` diff --git a/sentinel-extension/sentinel-datasource-nacos/src/main/java/com/alibaba/csp/sentinel/datasource/nacos/NacosDataSource.java b/sentinel-extension/sentinel-datasource-nacos/src/main/java/com/alibaba/csp/sentinel/datasource/nacos/NacosDataSource.java index 4da113a8..e8c7bcaa 100644 --- a/sentinel-extension/sentinel-datasource-nacos/src/main/java/com/alibaba/csp/sentinel/datasource/nacos/NacosDataSource.java +++ b/sentinel-extension/sentinel-datasource-nacos/src/main/java/com/alibaba/csp/sentinel/datasource/nacos/NacosDataSource.java @@ -23,8 +23,7 @@ import java.util.concurrent.TimeUnit; import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory; 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.alibaba.csp.sentinel.util.StringUtil; import com.alibaba.nacos.api.NacosFactory; @@ -32,7 +31,7 @@ import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.api.config.listener.Listener; /** - * A {@link DataSource} with Nacos backend. When the data in Nacos backend has been modified, + * A read-only {@code DataSource} with Nacos backend. When the data in Nacos backend has been modified, * Nacos will automatically push the new value so that the dynamic configuration can be real-time. * * @author Eric Zhao @@ -58,7 +57,7 @@ public class NacosDataSource extends AbstractDataSource { private ConfigService configService = null; /** - * Constructs an DataSource with Nacos backend. + * Constructs an read-only DataSource with Nacos backend. * * @param serverAddr server address of Nacos, cannot be empty * @param groupId group ID, cannot be empty @@ -66,7 +65,7 @@ public class NacosDataSource extends AbstractDataSource { * @param parser customized data parser, cannot be empty */ public NacosDataSource(final String serverAddr, final String groupId, final String dataId, - ConfigParser parser) { + Converter parser) { super(parser); if (StringUtil.isBlank(serverAddr) || StringUtil.isBlank(groupId) || StringUtil.isBlank(dataId)) { throw new IllegalArgumentException(String.format("Bad argument: serverAddr=[%s], groupId=[%s], dataId=[%s]", @@ -84,7 +83,7 @@ public class NacosDataSource extends AbstractDataSource { public void receiveConfigInfo(final String configInfo) { RecordLog.info(String.format("[NacosDataSource] New property value received for (%s, %s, %s): %s", serverAddr, dataId, groupId, configInfo)); - T newValue = NacosDataSource.this.parser.parse(configInfo); + T newValue = NacosDataSource.this.parser.convert(configInfo); // Update the new value to the property. getProperty().updateValue(newValue); } @@ -97,11 +96,11 @@ public class NacosDataSource extends AbstractDataSource { try { T newValue = loadConfig(); if (newValue == null) { - RecordLog.info("[NacosDataSource] WARN: initial config is null, you may have to check your data source"); + RecordLog.warn("[NacosDataSource] WARN: initial config is null, you may have to check your data source"); } getProperty().updateValue(newValue); } catch (Exception ex) { - RecordLog.info("[NacosDataSource] Error when loading initial config", ex); + RecordLog.warn("[NacosDataSource] Error when loading initial config", ex); } } @@ -111,7 +110,7 @@ public class NacosDataSource extends AbstractDataSource { // Add config listener. configService.addListener(dataId, groupId, configListener); } catch (Exception e) { - RecordLog.info("[NacosDataSource] Error occurred when initializing Nacos data source", e); + RecordLog.warn("[NacosDataSource] Error occurred when initializing Nacos data source", e); e.printStackTrace(); } } diff --git a/sentinel-extension/sentinel-datasource-zookeeper/README.md b/sentinel-extension/sentinel-datasource-zookeeper/README.md index 735b8a92..e207f979 100644 --- a/sentinel-extension/sentinel-datasource-zookeeper/README.md +++ b/sentinel-extension/sentinel-datasource-zookeeper/README.md @@ -18,7 +18,7 @@ For instance: ```java // `path` is the data path in ZooKeeper -DataSource> flowRuleDataSource = new ZookeeperDataSource<>(remoteAddress, path, source -> JSON.parseObject(source, new TypeReference>() {})); +ReadableDataSource> flowRuleDataSource = new ZookeeperDataSource<>(remoteAddress, path, source -> JSON.parseObject(source, new TypeReference>() {})); FlowRuleManager.register2Property(flowRuleDataSource.getProperty()); ``` diff --git a/sentinel-extension/sentinel-datasource-zookeeper/src/main/java/com/alibaba/csp/sentinel/datasource/zookeeper/ZookeeperDataSource.java b/sentinel-extension/sentinel-datasource-zookeeper/src/main/java/com/alibaba/csp/sentinel/datasource/zookeeper/ZookeeperDataSource.java index 09845f56..9094ffc5 100644 --- a/sentinel-extension/sentinel-datasource-zookeeper/src/main/java/com/alibaba/csp/sentinel/datasource/zookeeper/ZookeeperDataSource.java +++ b/sentinel-extension/sentinel-datasource-zookeeper/src/main/java/com/alibaba/csp/sentinel/datasource/zookeeper/ZookeeperDataSource.java @@ -7,7 +7,7 @@ import java.util.concurrent.TimeUnit; import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory; import com.alibaba.csp.sentinel.datasource.AbstractDataSource; -import com.alibaba.csp.sentinel.datasource.ConfigParser; +import com.alibaba.csp.sentinel.datasource.Converter; import com.alibaba.csp.sentinel.log.RecordLog; import com.alibaba.csp.sentinel.util.StringUtil; @@ -21,7 +21,7 @@ import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.data.Stat; /** - * Zookeeper DataSource + * A read-only {@code DataSource} with ZooKeeper backend. * * @author guonanjun */ @@ -40,7 +40,7 @@ public class ZookeeperDataSource extends AbstractDataSource { private CuratorFramework zkClient = null; private NodeCache nodeCache = null; - public ZookeeperDataSource(final String serverAddr, final String path, ConfigParser parser) { + public ZookeeperDataSource(final String serverAddr, final String path, Converter parser) { super(parser); if (StringUtil.isBlank(serverAddr) || StringUtil.isBlank(path)) { throw new IllegalArgumentException(String.format("Bad argument: serverAddr=[%s], path=[%s]", serverAddr, path)); @@ -54,7 +54,7 @@ public class ZookeeperDataSource extends AbstractDataSource { * This constructor is Nacos-style. */ public ZookeeperDataSource(final String serverAddr, final String groupId, final String dataId, - ConfigParser parser) { + Converter parser) { super(parser); if (StringUtil.isBlank(serverAddr) || StringUtil.isBlank(groupId) || StringUtil.isBlank(dataId)) { throw new IllegalArgumentException(String.format("Bad argument: serverAddr=[%s], groupId=[%s], dataId=[%s]", serverAddr, groupId, dataId)); @@ -73,11 +73,11 @@ public class ZookeeperDataSource extends AbstractDataSource { try { T newValue = loadConfig(); if (newValue == null) { - RecordLog.info("[ZookeeperDataSource] WARN: initial config is null, you may have to check your data source"); + RecordLog.warn("[ZookeeperDataSource] WARN: initial config is null, you may have to check your data source"); } getProperty().updateValue(newValue); } catch (Exception ex) { - RecordLog.info("[ZookeeperDataSource] Error when loading initial config", ex); + RecordLog.warn("[ZookeeperDataSource] Error when loading initial config", ex); } } @@ -95,7 +95,7 @@ public class ZookeeperDataSource extends AbstractDataSource { } RecordLog.info(String.format("[ZookeeperDataSource] New property value received for (%s, %s): %s", serverAddr, path, configInfo)); - T newValue = ZookeeperDataSource.this.parser.parse(configInfo); + T newValue = ZookeeperDataSource.this.parser.convert(configInfo); // Update the new value to the property. getProperty().updateValue(newValue); } @@ -112,7 +112,7 @@ public class ZookeeperDataSource extends AbstractDataSource { this.nodeCache.getListenable().addListener(this.listener, this.pool); this.nodeCache.start(); } catch (Exception e) { - RecordLog.info("[ZookeeperDataSource] Error occurred when initializing Zookeeper data source", e); + RecordLog.warn("[ZookeeperDataSource] Error occurred when initializing Zookeeper data source", e); e.printStackTrace(); } } diff --git a/sentinel-extension/sentinel-datasource-zookeeper/src/test/java/com/alibaba/csp/sentinel/datasource/zookeeper/ZookeeperDataSourceTest.java b/sentinel-extension/sentinel-datasource-zookeeper/src/test/java/com/alibaba/csp/sentinel/datasource/zookeeper/ZookeeperDataSourceTest.java index 11c51504..2425b7c2 100644 --- a/sentinel-extension/sentinel-datasource-zookeeper/src/test/java/com/alibaba/csp/sentinel/datasource/zookeeper/ZookeeperDataSourceTest.java +++ b/sentinel-extension/sentinel-datasource-zookeeper/src/test/java/com/alibaba/csp/sentinel/datasource/zookeeper/ZookeeperDataSourceTest.java @@ -3,8 +3,8 @@ package com.alibaba.csp.sentinel.datasource.zookeeper; import java.util.Collections; import java.util.List; -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.datasource.ReadableDataSource; import com.alibaba.csp.sentinel.slots.block.RuleConstant; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; @@ -34,10 +34,10 @@ public class ZookeeperDataSourceTest { final String remoteAddress = server.getConnectString(); final String path = "/sentinel-zk-ds-demo/flow-HK"; - DataSource> flowRuleDataSource = new ZookeeperDataSource>(remoteAddress, path, - new ConfigParser>() { + ReadableDataSource> flowRuleDataSource = new ZookeeperDataSource>(remoteAddress, path, + new Converter>() { @Override - public List parse(String source) { + public List convert(String source) { return JSON.parseObject(source, new TypeReference>() {}); } });