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(); } }