or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

base-classes.mdcore-interfaces.mdfile-datasources.mdindex.mdspecialized-datasources.md

file-datasources.mddocs/

0

# File Data Sources

1

2

File-based data source implementations providing automatic refresh capabilities for local file systems with configurable buffer sizes, character encodings, and refresh intervals.

3

4

## Capabilities

5

6

### FileRefreshableDataSource Class

7

8

The `FileRefreshableDataSource` class provides file-based readable data source with automatic refresh when the underlying file is modified.

9

10

```java { .api }

11

/**

12

* A ReadableDataSource based on file. This class will automatically

13

* fetches the backend file every refresh period when file is modified.

14

* Limitations: Default read buffer size is 1 MB. If file size is greater than

15

* buffer size, exceeding bytes will be ignored. Default charset is UTF-8.

16

* @param <T> target data type

17

*/

18

public class FileRefreshableDataSource<T> extends AutoRefreshDataSource<String, T> {

19

20

// Constants

21

public static final long DEFAULT_REFRESH_MS = 3000L;

22

public static final int DEFAULT_BUF_SIZE = 1024 * 1024; // 1 MB

23

public static final int MAX_SIZE = 1024 * 1024 * 4; // 4 MB

24

25

/**

26

* Create a file based ReadableDataSource with default settings.

27

* Buffer size: 1MB, charset: UTF-8, refresh interval: 3 seconds.

28

* @param file the file to read

29

* @param configParser the config decoder (parser)

30

* @throws FileNotFoundException if file doesn't exist or is a directory

31

*/

32

public FileRefreshableDataSource(File file, Converter<String, T> configParser)

33

throws FileNotFoundException;

34

35

/**

36

* Create a file based ReadableDataSource with filename.

37

* @param fileName the file name to read

38

* @param configParser the config decoder (parser)

39

* @throws FileNotFoundException if file doesn't exist or is a directory

40

*/

41

public FileRefreshableDataSource(String fileName, Converter<String, T> configParser)

42

throws FileNotFoundException;

43

44

/**

45

* Create a file based ReadableDataSource with custom buffer size.

46

* @param file the file to read

47

* @param configParser the config decoder (parser)

48

* @param bufSize buffer size for reading (must be between 0 and MAX_SIZE)

49

* @throws FileNotFoundException if file doesn't exist or is a directory

50

* @throws IllegalArgumentException if bufSize is invalid

51

*/

52

public FileRefreshableDataSource(File file, Converter<String, T> configParser, int bufSize)

53

throws FileNotFoundException;

54

55

/**

56

* Create a file based ReadableDataSource with custom charset.

57

* @param file the file to read

58

* @param configParser the config decoder (parser)

59

* @param charset character encoding for reading the file

60

* @throws FileNotFoundException if file doesn't exist or is a directory

61

* @throws IllegalArgumentException if charset is null

62

*/

63

public FileRefreshableDataSource(File file, Converter<String, T> configParser, Charset charset)

64

throws FileNotFoundException;

65

66

/**

67

* Create a file based ReadableDataSource with full customization.

68

* @param file the file to read

69

* @param configParser the config decoder (parser)

70

* @param recommendRefreshMs refresh interval in milliseconds

71

* @param bufSize buffer size for reading (must be between 0 and MAX_SIZE)

72

* @param charset character encoding for reading the file

73

* @throws FileNotFoundException if file doesn't exist or is a directory

74

* @throws IllegalArgumentException if parameters are invalid

75

*/

76

public FileRefreshableDataSource(File file, Converter<String, T> configParser,

77

long recommendRefreshMs, int bufSize, Charset charset) throws FileNotFoundException;

78

79

/**

80

* Read file content as string.

81

* @return file content as string with specified charset

82

* @throws Exception if file reading fails

83

*/

84

public String readSource() throws Exception;

85

86

/**

87

* Check if file was modified since last read.

88

* @return true if file modification time changed

89

*/

90

protected boolean isModified();

91

92

/**

93

* Close data source and clean up resources.

94

* @throws Exception if cleanup fails

95

*/

96

public void close() throws Exception;

97

}

98

```

99

100

**Usage Examples:**

101

102

```java

103

// Basic file monitoring with JSON rules

104

Converter<String, List<FlowRule>> jsonConverter = source -> {

105

if (source == null || source.trim().isEmpty()) {

106

return new ArrayList<>();

107

}

108

return JSON.parseArray(source, FlowRule.class);

109

};

110

111

// Monitor flow rules file

112

FileRefreshableDataSource<List<FlowRule>> flowRuleDs =

113

new FileRefreshableDataSource<>(

114

new File("/sentinel/flow-rules.json"),

115

jsonConverter

116

);

117

118

// Register for automatic rule updates

119

flowRuleDs.getProperty().addListener(rules -> {

120

FlowRuleManager.loadRules(rules);

121

System.out.println("Flow rules updated: " + rules.size() + " rules");

122

});

123

124

// Custom buffer size and charset for large configuration files

125

FileRefreshableDataSource<List<DegradeRule>> degradeRuleDs =

126

new FileRefreshableDataSource<>(

127

new File("/sentinel/degrade-rules.xml"),

128

xmlConverter,

129

2 * 1024 * 1024, // 2MB buffer

130

StandardCharsets.UTF_16

131

);

132

133

// Fast refresh for development

134

FileRefreshableDataSource<List<SystemRule>> devSystemRuleDs =

135

new FileRefreshableDataSource<>(

136

new File("/dev/system-rules.json"),

137

systemRuleConverter,

138

1000, // 1 second refresh

139

DEFAULT_BUF_SIZE,

140

StandardCharsets.UTF_8

141

);

142

```

143

144

### FileWritableDataSource Class

145

146

The `FileWritableDataSource` class provides thread-safe file writing capabilities for persisting configuration changes.

147

148

```java { .api }

149

/**

150

* A WritableDataSource based on file.

151

* @param <T> data type

152

*/

153

public class FileWritableDataSource<T> implements WritableDataSource<T> {

154

155

/**

156

* Create a file writable data source with file path.

157

* @param filePath path to the target file

158

* @param configEncoder converter from data to string

159

* @throws IllegalArgumentException if parameters are invalid

160

*/

161

public FileWritableDataSource(String filePath, Converter<T, String> configEncoder);

162

163

/**

164

* Create a file writable data source with File object.

165

* @param file the target file

166

* @param configEncoder converter from data to string

167

* @throws IllegalArgumentException if file is null, directory, or configEncoder is null

168

*/

169

public FileWritableDataSource(File file, Converter<T, String> configEncoder);

170

171

/**

172

* Create a file writable data source with custom charset.

173

* @param file the target file

174

* @param configEncoder converter from data to string

175

* @param charset character encoding for writing

176

* @throws IllegalArgumentException if any parameter is null or file is directory

177

*/

178

public FileWritableDataSource(File file, Converter<T, String> configEncoder, Charset charset);

179

180

/**

181

* Write value to file in a thread-safe manner.

182

* @param value value to write

183

* @throws Exception if file writing fails

184

*/

185

public void write(T value) throws Exception;

186

187

/**

188

* Close data source (no-op for file implementation).

189

* @throws Exception if cleanup fails

190

*/

191

public void close() throws Exception;

192

}

193

```

194

195

**Usage Examples:**

196

197

```java

198

// JSON encoder for flow rules

199

Converter<List<FlowRule>, String> flowRuleEncoder = rules -> {

200

return JSON.toJSONString(rules, true); // Pretty print

201

};

202

203

// Writable data source for persisting rule changes

204

FileWritableDataSource<List<FlowRule>> writableDs =

205

new FileWritableDataSource<>(

206

"/sentinel/flow-rules.json",

207

flowRuleEncoder

208

);

209

210

// Write updated rules

211

List<FlowRule> newRules = Arrays.asList(

212

new FlowRule()

213

.setResource("GET:/api/users")

214

.setCount(100)

215

.setGrade(RuleConstant.FLOW_GRADE_QPS),

216

new FlowRule()

217

.setResource("POST:/api/orders")

218

.setCount(50)

219

.setGrade(RuleConstant.FLOW_GRADE_QPS)

220

);

221

222

writableDs.write(newRules);

223

224

// XML encoder with custom charset

225

Converter<List<DegradeRule>, String> xmlEncoder = rules -> {

226

StringBuilder xml = new StringBuilder();

227

xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");

228

xml.append("<rules>\n");

229

230

for (DegradeRule rule : rules) {

231

xml.append(" <rule resource=\"").append(rule.getResource()).append("\"")

232

.append(" count=\"").append(rule.getCount()).append("\"")

233

.append(" timeWindow=\"").append(rule.getTimeWindow()).append("\"/>\n");

234

}

235

236

xml.append("</rules>");

237

return xml.toString();

238

};

239

240

FileWritableDataSource<List<DegradeRule>> xmlWriter =

241

new FileWritableDataSource<>(

242

new File("/config/degrade-rules.xml"),

243

xmlEncoder,

244

StandardCharsets.UTF_8

245

);

246

```

247

248

## Integration Patterns

249

250

### Read-Write Configuration Management

251

252

Combine readable and writable data sources for complete configuration management:

253

254

```java

255

// Setup read and write data sources for the same file

256

File configFile = new File("/sentinel/flow-rules.json");

257

258

Converter<String, List<FlowRule>> reader = source ->

259

JSON.parseArray(source, FlowRule.class);

260

261

Converter<List<FlowRule>, String> writer = rules ->

262

JSON.toJSONString(rules, true);

263

264

// Readable data source with auto-refresh

265

FileRefreshableDataSource<List<FlowRule>> readableDs =

266

new FileRefreshableDataSource<>(configFile, reader);

267

268

// Writable data source for updates

269

FileWritableDataSource<List<FlowRule>> writableDs =

270

new FileWritableDataSource<>(configFile, writer);

271

272

// Dynamic rule management

273

readableDs.getProperty().addListener(FlowRuleManager::loadRules);

274

275

// API endpoint for rule updates

276

@PostMapping("/flow-rules")

277

public ResponseEntity<String> updateFlowRules(@RequestBody List<FlowRule> rules) {

278

try {

279

writableDs.write(rules);

280

return ResponseEntity.ok("Rules updated successfully");

281

} catch (Exception e) {

282

return ResponseEntity.status(500).body("Failed to update rules: " + e.getMessage());

283

}

284

}

285

```

286

287

### Configuration File Formats

288

289

Support multiple configuration formats through different converters:

290

291

```java

292

// YAML converter

293

Converter<String, List<FlowRule>> yamlConverter = source -> {

294

Yaml yaml = new Yaml();

295

Map<String, Object> data = yaml.load(source);

296

List<Map<String, Object>> rulesData = (List<Map<String, Object>>) data.get("flowRules");

297

298

return rulesData.stream()

299

.map(ruleData -> new FlowRule()

300

.setResource((String) ruleData.get("resource"))

301

.setCount(((Number) ruleData.get("count")).doubleValue()))

302

.collect(Collectors.toList());

303

};

304

305

// Properties converter

306

Converter<String, List<FlowRule>> propsConverter = source -> {

307

Properties props = new Properties();

308

props.load(new StringReader(source));

309

310

List<FlowRule> rules = new ArrayList<>();

311

for (String key : props.stringPropertyNames()) {

312

if (key.startsWith("flow.rule.")) {

313

String resource = key.substring("flow.rule.".length());

314

double count = Double.parseDouble(props.getProperty(key));

315

rules.add(new FlowRule().setResource(resource).setCount(count));

316

}

317

}

318

return rules;

319

};

320

```

321

322

## Error Handling and Limitations

323

324

### File Size Limitations

325

326

- **Default buffer size**: 1 MB

327

- **Maximum buffer size**: 4 MB

328

- **Behavior**: Files larger than buffer size will be truncated

329

- **Recommendation**: Use appropriate buffer size for your configuration files

330

331

### Character Encoding

332

333

- **Default charset**: UTF-8

334

- **Custom charset**: Specify in constructor

335

- **Encoding consistency**: Ensure read and write operations use same charset

336

337

### Thread Safety

338

339

- **FileRefreshableDataSource**: Thread-safe for concurrent reads

340

- **FileWritableDataSource**: Uses `ReentrantLock` for thread-safe writes

341

- **File system**: Handles concurrent access through proper locking mechanisms