Extensible data source implementations for Sentinel flow control and circuit breaker library.
—
The core interfaces define the fundamental contracts for data source operations in Sentinel DataSource Extension. These interfaces provide the foundation for all readable and writable data source implementations.
The ReadableDataSource interface is responsible for retrieving configurations in a read-only manner. It supports generic type parameters for both source and target data types.
/**
* The readable data source is responsible for retrieving configs (read-only).
* @param <S> source data type
* @param <T> target data type
*/
public interface ReadableDataSource<S, T> {
/**
* Load data from data source as the target type.
* @return the target data
* @throws Exception IO or other error occurs
*/
T loadConfig() throws Exception;
/**
* Read original data from the data source.
* @return the original data
* @throws Exception IO or other error occurs
*/
S readSource() throws Exception;
/**
* Get SentinelProperty of the data source.
* @return the property for dynamic updates
*/
SentinelProperty<T> getProperty();
/**
* Close the data source.
* @throws Exception IO or other error occurs
*/
void close() throws Exception;
}Usage Examples:
// Example: Custom database-backed readable data source
public class DatabaseReadableDataSource implements ReadableDataSource<ResultSet, List<FlowRule>> {
private final String connectionUrl;
private final Converter<ResultSet, List<FlowRule>> converter;
@Override
public List<FlowRule> loadConfig() throws Exception {
ResultSet rs = readSource();
return converter.convert(rs);
}
@Override
public ResultSet readSource() throws Exception {
Connection conn = DriverManager.getConnection(connectionUrl);
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM flow_rules");
return stmt.executeQuery();
}
@Override
public SentinelProperty<List<FlowRule>> getProperty() {
return property;
}
@Override
public void close() throws Exception {
// Close database connections
}
}The WritableDataSource interface provides write capability to data sources, enabling dynamic rule updates and configuration persistence.
/**
* Interface of writable data source support.
* @param <T> data type
*/
public interface WritableDataSource<T> {
/**
* Write the value to the data source.
* @param value value to write
* @throws Exception IO or other error occurs
*/
void write(T value) throws Exception;
/**
* Close the data source.
* @throws Exception IO or other error occurs
*/
void close() throws Exception;
}Usage Examples:
// Example: Using file writable data source
Converter<List<FlowRule>, String> encoder = rules ->
JSON.toJSONString(rules, true);
WritableDataSource<List<FlowRule>> writableDs =
new FileWritableDataSource<>("/sentinel/rules.json", encoder);
// Write new rules
List<FlowRule> newRules = Arrays.asList(
new FlowRule().setResource("GET:/api/users").setCount(100),
new FlowRule().setResource("GET:/api/orders").setCount(50)
);
writableDs.write(newRules);The Converter interface enables transformation between different data types, providing flexibility in data format handling.
/**
* Convert an object from source type S to target type T.
* @param <S> source type
* @param <T> target type
*/
public interface Converter<S, T> {
/**
* Convert source to the target type.
* @param source the source object
* @return the target object
*/
T convert(S source);
}Usage Examples:
// JSON string to FlowRule list converter
Converter<String, List<FlowRule>> jsonConverter = source -> {
if (source == null || source.trim().isEmpty()) {
return new ArrayList<>();
}
return JSON.parseArray(source, FlowRule.class);
};
// FlowRule list to JSON string converter
Converter<List<FlowRule>, String> ruleEncoder = rules -> {
return JSON.toJSONString(rules, true);
};
// XML string to DegradeRule list converter
Converter<String, List<DegradeRule>> xmlConverter = source -> {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream(source.getBytes()));
List<DegradeRule> rules = new ArrayList<>();
NodeList ruleNodes = doc.getElementsByTagName("rule");
for (int i = 0; i < ruleNodes.getLength(); i++) {
Element ruleElement = (Element) ruleNodes.item(i);
DegradeRule rule = new DegradeRule();
rule.setResource(ruleElement.getAttribute("resource"));
rule.setCount(Double.parseDouble(ruleElement.getAttribute("count")));
rules.add(rule);
}
return rules;
};All readable data sources integrate with Sentinel's property system to enable dynamic configuration updates:
// Set up dynamic rule loading
ReadableDataSource<String, List<FlowRule>> ds =
new FileRefreshableDataSource<>("/sentinel/flow-rules.json", jsonConverter);
// Register property listener for automatic rule updates
ds.getProperty().addListener(rules -> {
FlowRuleManager.loadRules(rules);
System.out.println("Flow rules updated: " + rules.size() + " rules loaded");
});All interface methods that perform I/O operations declare throws Exception, allowing implementations to handle various error conditions:
Install with Tessl CLI
npx tessl i tessl/maven-com-alibaba-csp--sentinel-datasource-extension