Skip to content

Commit

Permalink
Revise #19808 (#19950)
Browse files Browse the repository at this point in the history
* Refactor AbstractReadwriteSplittingRuleConfigurationChecker

* Refactor ReadwriteSplittingRule
  • Loading branch information
terrymanu authored Aug 7, 2022
1 parent aa254d0 commit 20cc50a
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,30 +54,41 @@ public final void check(final String databaseName, final T config, final Map<Str
checkLoadBalancerDataSourceName(databaseName, configs, getLoadBalancer(config), rules);
}

private void checkDataSources(final String databaseName, final Collection<ReadwriteSplittingDataSourceRuleConfiguration> configs,
final Map<String, DataSource> dataSourceMap, final Collection<ShardingSphereRule> rules) {
Collection<String> writeDataSourceNames = new HashSet<>();
Collection<String> readDataSourceNames = new HashSet<>();
private void checkDataSources(final String databaseName,
final Collection<ReadwriteSplittingDataSourceRuleConfiguration> configs, final Map<String, DataSource> dataSourceMap, final Collection<ShardingSphereRule> rules) {
Collection<String> addedWriteDataSourceNames = new HashSet<>();
Collection<String> addedReadDataSourceNames = new HashSet<>();
for (ReadwriteSplittingDataSourceRuleConfiguration each : configs) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(each.getName()), "Name is required.");
Preconditions.checkState(null != each.getStaticStrategy() || null != each.getDynamicStrategy(),
"No available readwrite-splitting rule configuration in database `%s`.", databaseName);
Optional.ofNullable(each.getStaticStrategy()).ifPresent(optional -> checkStaticStrategy(databaseName, dataSourceMap, writeDataSourceNames, readDataSourceNames, optional));
Preconditions.checkArgument(!Strings.isNullOrEmpty(each.getName()), "Readwrite-splitting data source name is required.");
Preconditions.checkState(null != each.getStaticStrategy() || null != each.getDynamicStrategy(), "No available readwrite-splitting rule configuration in database `%s`.", databaseName);
Optional.ofNullable(each.getStaticStrategy()).ifPresent(optional -> checkStaticStrategy(databaseName, dataSourceMap, addedWriteDataSourceNames, addedReadDataSourceNames, optional));
Optional.ofNullable(each.getDynamicStrategy()).ifPresent(optional -> checkDynamicStrategy(rules, optional));
}
}

private void checkStaticStrategy(final String databaseName, final Map<String, DataSource> dataSourceMap, final Collection<String> writeDataSourceNames,
private void checkStaticStrategy(final String databaseName, final Map<String, DataSource> dataSourceMap, final Collection<String> addedWriteDataSourceNames,
final Collection<String> readDataSourceNames, final StaticReadwriteSplittingStrategyConfiguration strategyConfig) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(strategyConfig.getWriteDataSourceName()), "Write data source name is required.");
Preconditions.checkArgument(!strategyConfig.getReadDataSourceNames().isEmpty(), "Read data source names are required.");
Collection<String> inlineWriteNames = new InlineExpressionParser(strategyConfig.getWriteDataSourceName()).splitAndEvaluate();
inlineWriteNames.forEach(each -> Preconditions.checkState(null != dataSourceMap.get(each), "Write data source name `%s` not in database `%s`.", each, databaseName));
inlineWriteNames.forEach(each -> Preconditions.checkState(writeDataSourceNames.add(each), "Can not config duplicate write dataSource `%s` in database `%s`.", each, databaseName));
for (String readName : readDataSourceNames) {
Collection<String> inlineReadNames = new InlineExpressionParser(readName).splitAndEvaluate();
inlineReadNames.forEach(each -> Preconditions.checkState(null != dataSourceMap.get(each), "Read data source name `%s` not in database `%s`.", each, databaseName));
inlineReadNames.forEach(each -> Preconditions.checkState(readDataSourceNames.add(each), "Can not config duplicate write dataSource `%s` in database `%s`.", each, databaseName));
checkWriteDataSourceNames(databaseName, dataSourceMap, addedWriteDataSourceNames, strategyConfig);
for (String each : readDataSourceNames) {
checkReadeDataSourceNames(databaseName, dataSourceMap, readDataSourceNames, each);
}
}

private void checkWriteDataSourceNames(final String databaseName, final Map<String, DataSource> dataSourceMap,
final Collection<String> addedWriteDataSourceNames, final StaticReadwriteSplittingStrategyConfiguration strategyConfig) {
for (String each : new InlineExpressionParser(strategyConfig.getWriteDataSourceName()).splitAndEvaluate()) {
Preconditions.checkState(dataSourceMap.containsKey(each), "Write data source name `%s` not in database `%s`.", each, databaseName);
Preconditions.checkState(addedWriteDataSourceNames.add(each), "Can not config duplicate write data source `%s` in database `%s`.", each, databaseName);
}
}

private void checkReadeDataSourceNames(final String databaseName,
final Map<String, DataSource> dataSourceMap, final Collection<String> addedReadDataSourceNames, final String readDataSourceName) {
for (String each : new InlineExpressionParser(readDataSourceName).splitAndEvaluate()) {
Preconditions.checkState(dataSourceMap.containsKey(each), "Read data source name `%s` not in database `%s`.", each, databaseName);
Preconditions.checkState(addedReadDataSourceNames.add(each), "Can not config duplicate write data source `%s` in database `%s`.", each, databaseName);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public ReadwriteSplittingRule(final ReadwriteSplittingRuleConfiguration ruleConf
ruleConfig.getLoadBalancers().forEach((key, value) -> loadBalancers.put(key, ReadQueryLoadBalanceAlgorithmFactory.newInstance(value)));
dataSourceRules = new HashMap<>(ruleConfig.getDataSources().size(), 1);
for (ReadwriteSplittingDataSourceRuleConfiguration each : ruleConfig.getDataSources()) {
dataSourceRules.putAll(buildReadwriteSplittingDataSourceRules(each, builtRules));
dataSourceRules.putAll(createReadwriteSplittingDataSourceRules(each, builtRules));
}
}

Expand All @@ -78,58 +78,64 @@ public ReadwriteSplittingRule(final AlgorithmProvidedReadwriteSplittingRuleConfi
loadBalancers.putAll(ruleConfig.getLoadBalanceAlgorithms());
dataSourceRules = new HashMap<>(ruleConfig.getDataSources().size(), 1);
for (ReadwriteSplittingDataSourceRuleConfiguration each : ruleConfig.getDataSources()) {
dataSourceRules.putAll(buildReadwriteSplittingDataSourceRules(each, builtRules));
dataSourceRules.putAll(createReadwriteSplittingDataSourceRules(each, builtRules));
}
}

private Map<String, ReadwriteSplittingDataSourceRule> buildReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config,
final Collection<ShardingSphereRule> builtRules) {
ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm = null == loadBalancers.get(config.getLoadBalancerName())
? ReadQueryLoadBalanceAlgorithmFactory.newInstance()
: loadBalancers.get(config.getLoadBalancerName());
if (null != config.getStaticStrategy()) {
return buildStaticReadwriteSplittingDataSourceRules(config, builtRules, loadBalanceAlgorithm);
} else {
return buildDynamicReadwriteSplittingDataSourceRules(config, builtRules, loadBalanceAlgorithm);
}
private Map<String, ReadwriteSplittingDataSourceRule> createReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config,
final Collection<ShardingSphereRule> builtRules) {
ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm = loadBalancers.getOrDefault(config.getLoadBalancerName(), ReadQueryLoadBalanceAlgorithmFactory.newInstance());
return null == config.getStaticStrategy()
? createDynamicReadwriteSplittingDataSourceRules(config, builtRules, loadBalanceAlgorithm)
: createStaticReadwriteSplittingDataSourceRules(config, builtRules, loadBalanceAlgorithm);
}

private Map<String, ReadwriteSplittingDataSourceRule> buildStaticReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config,
final Collection<ShardingSphereRule> builtRules,
final ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm) {
private Map<String, ReadwriteSplittingDataSourceRule> createStaticReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config,
final Collection<ShardingSphereRule> builtRules,
final ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm) {
Map<String, ReadwriteSplittingDataSourceRule> result = new LinkedHashMap<>();
List<String> readwriteInlineNames = new InlineExpressionParser(config.getName()).splitAndEvaluate();
List<String> writeInlineDatasourceNames = new InlineExpressionParser(config.getStaticStrategy().getWriteDataSourceName()).splitAndEvaluate();
List<List<String>> readInlineDatasourceNames = config.getStaticStrategy().getReadDataSourceNames().stream()
List<String> inlineReadwriteDataSourceNames = new InlineExpressionParser(config.getName()).splitAndEvaluate();
List<String> inlineWriteDatasourceNames = new InlineExpressionParser(config.getStaticStrategy().getWriteDataSourceName()).splitAndEvaluate();
List<List<String>> inlineReadDatasourceNames = config.getStaticStrategy().getReadDataSourceNames().stream()
.map(each -> new InlineExpressionParser(each).splitAndEvaluate()).collect(Collectors.toList());
Preconditions.checkArgument(writeInlineDatasourceNames.size() == readwriteInlineNames.size(), "Inline expression write data source names size error");
readInlineDatasourceNames.forEach(e -> Preconditions.checkArgument(e.size() == readwriteInlineNames.size(), "Inline expression read data source names size error"));
for (int i = 0; i < readwriteInlineNames.size(); i++) {
final int index = i;
ReadwriteSplittingDataSourceRuleConfiguration staticConfig = new ReadwriteSplittingDataSourceRuleConfiguration(readwriteInlineNames.get(index),
new StaticReadwriteSplittingStrategyConfiguration(writeInlineDatasourceNames.get(index),
readInlineDatasourceNames.stream().map(each -> each.get(index)).collect(Collectors.toList())),
null, config.getLoadBalancerName());
result.put(readwriteInlineNames.get(i), new ReadwriteSplittingDataSourceRule(staticConfig, loadBalanceAlgorithm, builtRules));
Preconditions.checkArgument(inlineWriteDatasourceNames.size() == inlineReadwriteDataSourceNames.size(), "Inline expression write data source names size error");
inlineReadDatasourceNames.forEach(each -> Preconditions.checkArgument(each.size() == inlineReadwriteDataSourceNames.size(), "Inline expression read data source names size error"));
for (int i = 0; i < inlineReadwriteDataSourceNames.size(); i++) {
ReadwriteSplittingDataSourceRuleConfiguration staticConfig = createStaticDataSourceRuleConfiguration(
config, i, inlineReadwriteDataSourceNames, inlineWriteDatasourceNames, inlineReadDatasourceNames);
result.put(inlineReadwriteDataSourceNames.get(i), new ReadwriteSplittingDataSourceRule(staticConfig, loadBalanceAlgorithm, builtRules));
}
return result;
}

private Map<String, ReadwriteSplittingDataSourceRule> buildDynamicReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config,
final Collection<ShardingSphereRule> builtRules,
final ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm) {

private ReadwriteSplittingDataSourceRuleConfiguration createStaticDataSourceRuleConfiguration(final ReadwriteSplittingDataSourceRuleConfiguration config, final int index,
final List<String> readwriteDataSourceNames, final List<String> writeDatasourceNames,
final List<List<String>> readDatasourceNames) {
List<String> readDataSourceNames = readDatasourceNames.stream().map(each -> each.get(index)).collect(Collectors.toList());
return new ReadwriteSplittingDataSourceRuleConfiguration(readwriteDataSourceNames.get(index),
new StaticReadwriteSplittingStrategyConfiguration(writeDatasourceNames.get(index), readDataSourceNames), null, config.getLoadBalancerName());
}

private Map<String, ReadwriteSplittingDataSourceRule> createDynamicReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config,
final Collection<ShardingSphereRule> builtRules,
final ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm) {
Map<String, ReadwriteSplittingDataSourceRule> result = new LinkedHashMap<>();
List<String> readwriteInlineNames = new InlineExpressionParser(config.getName()).splitAndEvaluate();
List<String> autoAwareNames = new InlineExpressionParser(config.getDynamicStrategy().getAutoAwareDataSourceName()).splitAndEvaluate();
Preconditions.checkArgument(autoAwareNames.size() == readwriteInlineNames.size(), "Inline expression auto aware data source names size error");
for (int i = 0; i < readwriteInlineNames.size(); i++) {
ReadwriteSplittingDataSourceRuleConfiguration dynamicConfig = new ReadwriteSplittingDataSourceRuleConfiguration(readwriteInlineNames.get(i), null,
new DynamicReadwriteSplittingStrategyConfiguration(autoAwareNames.get(i), config.getDynamicStrategy().getWriteDataSourceQueryEnabled()), config.getLoadBalancerName());
result.put(readwriteInlineNames.get(i), new ReadwriteSplittingDataSourceRule(dynamicConfig, loadBalanceAlgorithm, builtRules));
List<String> inlineReadwriteDataSourceNames = new InlineExpressionParser(config.getName()).splitAndEvaluate();
List<String> inlineAutoAwareDataSourceNames = new InlineExpressionParser(config.getDynamicStrategy().getAutoAwareDataSourceName()).splitAndEvaluate();
Preconditions.checkArgument(inlineAutoAwareDataSourceNames.size() == inlineReadwriteDataSourceNames.size(), "Inline expression auto aware data source names size error");
for (int i = 0; i < inlineReadwriteDataSourceNames.size(); i++) {
ReadwriteSplittingDataSourceRuleConfiguration dynamicConfig = createDynamicDataSourceRuleConfiguration(config, i, inlineReadwriteDataSourceNames, inlineAutoAwareDataSourceNames);
result.put(inlineReadwriteDataSourceNames.get(i), new ReadwriteSplittingDataSourceRule(dynamicConfig, loadBalanceAlgorithm, builtRules));
}
return result;
}


private ReadwriteSplittingDataSourceRuleConfiguration createDynamicDataSourceRuleConfiguration(final ReadwriteSplittingDataSourceRuleConfiguration config, final int index,
final List<String> readwriteDataSourceNames, final List<String> autoAwareDataSourceNames) {
return new ReadwriteSplittingDataSourceRuleConfiguration(readwriteDataSourceNames.get(index), null,
new DynamicReadwriteSplittingStrategyConfiguration(autoAwareDataSourceNames.get(index), config.getDynamicStrategy().getWriteDataSourceQueryEnabled()), config.getLoadBalancerName());
}

/**
* Get single data source rule.
*
Expand Down

0 comments on commit 20cc50a

Please sign in to comment.