001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.support.sentinel.datasource;
017
018import com.alibaba.csp.sentinel.datasource.AbstractDataSource;
019import com.alibaba.csp.sentinel.datasource.Converter;
020import com.jfinal.kit.LogKit;
021import io.jboot.utils.FileUtil;
022import io.jboot.utils.QuietlyUtil;
023
024import java.io.File;
025
026public class FileDataSource<T> extends AbstractDataSource<String, T> {
027
028    private File file;
029
030    private boolean fileExists;
031    private long fileLastModified = -1;
032    private long fileLength = -1;
033    private boolean isClosed = false;
034
035    public FileDataSource(File file, Converter<String, T> parser) {
036        super(parser);
037        this.file = file;
038        this.fileExists = file.exists();
039
040        if (this.fileExists) {
041            this.fileLastModified = file.lastModified();
042            this.fileLength = file.length();
043        }
044
045        updateProperties();
046
047        new Thread(() -> {
048            while (!isClosed) {
049                try {
050                    doReadAndUpdateProperties();
051                } catch (Exception ex) {
052                    LogKit.error(ex.toString(), ex);
053                }
054                QuietlyUtil.sleepQuietly(5000);
055            }
056        }, "jboot-sentinel-file-reader").start();
057    }
058
059
060    private void doReadAndUpdateProperties() {
061        boolean fileExists = file.exists();
062        long fileLastModified = fileExists ? file.lastModified() : -1;
063        long fileLength = fileExists ? file.length() : -1;
064
065        if (this.fileExists != fileExists
066                || this.fileLength != fileLength
067                || this.fileLastModified != fileLastModified) {
068
069            updateProperties();
070
071            this.fileExists = fileExists;
072            this.fileLastModified = fileLastModified;
073            this.fileLength = fileLength;
074        }
075    }
076
077
078    private void updateProperties() {
079        String content = file.exists() ? FileUtil.readString(file) : "";
080        getProperty().updateValue(parser.convert(content));
081    }
082
083
084    @Override
085    public String readSource() throws Exception {
086        return FileUtil.readString(file);
087    }
088
089
090    @Override
091    public void close() throws Exception {
092        isClosed = true;
093    }
094}