diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/FlowRuleManager.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/FlowRuleManager.java
index e0dac47a..f09701ae 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/FlowRuleManager.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/FlowRuleManager.java
@@ -110,6 +110,9 @@ public class FlowRuleManager {
}
for (FlowRule rule : list) {
+ if (!isValid(rule)) {
+ continue;
+ }
if (StringUtil.isBlank(rule.getLimitApp())) {
rule.setLimitApp(FlowRule.LIMIT_APP_DEFAULT);
}
@@ -199,4 +202,7 @@ public class FlowRuleManager {
}
+ private static boolean isValid(FlowRule rule) {
+ return rule != null && !StringUtil.isBlank(rule.getResource());
+ }
}
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 cca5fa6e..f2a8ab3e 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
@@ -25,10 +25,8 @@ import com.alibaba.csp.sentinel.log.RecordLog;
/**
* A {@link ReadableDataSource} automatically fetches the backend data.
*
- * @param
- * source data type
- * @param
- * target data type
+ * @param source data type
+ * @param target data type
* @author Carpenter Lee
*/
public abstract class AutoRefreshDataSource extends AbstractDataSource {
@@ -52,12 +50,12 @@ public abstract class AutoRefreshDataSource extends AbstractDataSource extends AbstractDataSource
* A {@link ReadableDataSource} based on file. This class will automatically
- * fetches the backend file every refresh period.
+ * fetches the backend file every isModified period.
*
*
* Limitations: Default read buffer size is 1 MB. If file size is greater than
@@ -46,16 +46,15 @@ public class FileRefreshableDataSource extends AutoRefreshDataSource configParser) throws FileNotFoundException {
this(file, configParser, DEFAULT_REFRESH_MS, DEFAULT_BUF_SIZE, DEFAULT_CHAR_SET);
@@ -66,23 +65,23 @@ public class FileRefreshableDataSource extends AutoRefreshDataSource configParser, int bufSize)
- throws FileNotFoundException {
+ throws FileNotFoundException {
this(file, configParser, DEFAULT_REFRESH_MS, bufSize, DEFAULT_CHAR_SET);
}
public FileRefreshableDataSource(File file, Converter configParser, Charset charset)
- throws FileNotFoundException {
+ throws FileNotFoundException {
this(file, configParser, DEFAULT_REFRESH_MS, DEFAULT_BUF_SIZE, charset);
}
public FileRefreshableDataSource(File file, Converter configParser, long recommendRefreshMs, int bufSize,
- Charset charset) throws FileNotFoundException {
+ Charset charset) throws FileNotFoundException {
super(configParser, recommendRefreshMs);
if (bufSize <= 0 || bufSize > MAX_SIZE) {
throw new IllegalArgumentException("bufSize must between (0, " + MAX_SIZE + "], but " + bufSize + " get");
}
- if (file == null) {
- throw new IllegalArgumentException("file can't be null");
+ if (file == null || file.isDirectory()) {
+ throw new IllegalArgumentException("File can't be null or a directory");
}
if (charset == null) {
throw new IllegalArgumentException("charset can't be null");
@@ -90,6 +89,7 @@ public class FileRefreshableDataSource extends AutoRefreshDataSource extends AutoRefreshDataSource buf.length) {
throw new IllegalStateException(file.getAbsolutePath() + " file size=" + channel.size()
- + ", is bigger than bufSize=" + buf.length + ". Can't read");
+ + ", is bigger than bufSize=" + buf.length + ". Can't read");
}
int len = inputStream.read(buf);
return new String(buf, 0, len, charset);
@@ -126,8 +130,8 @@ public class FileRefreshableDataSource extends AutoRefreshDataSource
- * data type
+ * @param data type
* @author Eric Zhao
* @since 0.2.0
*/
public class FileWritableDataSource implements WritableDataSource {
+ private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
+
private final Converter configEncoder;
- private File file;
+ private final File file;
+ private final Charset charset;
+
+ private final Lock lock = new ReentrantLock(true);
public FileWritableDataSource(String filePath, Converter configEncoder) {
this(new File(filePath), configEncoder);
}
public FileWritableDataSource(File file, Converter configEncoder) {
+ this(file, configEncoder, DEFAULT_CHARSET);
+ }
+
+ public FileWritableDataSource(File file, Converter configEncoder, Charset charset) {
if (file == null || file.isDirectory()) {
throw new IllegalArgumentException("Bad file");
}
if (configEncoder == null) {
throw new IllegalArgumentException("Config encoder cannot be null");
}
+ if (charset == null) {
+ throw new IllegalArgumentException("Charset cannot be null");
+ }
this.configEncoder = configEncoder;
this.file = file;
+ this.charset = charset;
}
@Override
public void write(T value) throws Exception {
- if (configEncoder == null) {
- throw new NullPointerException("configEncoder is null Can't write");
- }
- synchronized (file) {
+ lock.lock();
+ try {
String convertResult = configEncoder.convert(value);
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
- byte[] bytesArray = convertResult.getBytes();
+ byte[] bytesArray = convertResult.getBytes(charset);
+
+ RecordLog.info(String.format("[FileWritableDataSource] Writing to file %s: %s", file.toString(), convertResult));
outputStream.write(bytesArray);
outputStream.flush();
} finally {
@@ -68,6 +85,8 @@ public class FileWritableDataSource implements WritableDataSource {
}
}
}
+ } finally {
+ lock.unlock();
}
}