From 20cc50ae010a57fb252362e23cb52bcd795e506a Mon Sep 17 00:00:00 2001 From: Liang Zhang Date: Mon, 8 Aug 2022 00:12:43 +0800 Subject: [PATCH] Revise #19808 (#19950) * Refactor AbstractReadwriteSplittingRuleConfigurationChecker * Refactor ReadwriteSplittingRule --- ...riteSplittingRuleConfigurationChecker.java | 43 ++++++---- .../rule/ReadwriteSplittingRule.java | 86 ++++++++++--------- 2 files changed, 73 insertions(+), 56 deletions(-) diff --git a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/AbstractReadwriteSplittingRuleConfigurationChecker.java b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/AbstractReadwriteSplittingRuleConfigurationChecker.java index 157696a1835c9..3d2381a8fdb01 100644 --- a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/AbstractReadwriteSplittingRuleConfigurationChecker.java +++ b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/AbstractReadwriteSplittingRuleConfigurationChecker.java @@ -54,30 +54,41 @@ public final void check(final String databaseName, final T config, final Map configs, - final Map dataSourceMap, final Collection rules) { - Collection writeDataSourceNames = new HashSet<>(); - Collection readDataSourceNames = new HashSet<>(); + private void checkDataSources(final String databaseName, + final Collection configs, final Map dataSourceMap, final Collection rules) { + Collection addedWriteDataSourceNames = new HashSet<>(); + Collection 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 dataSourceMap, final Collection writeDataSourceNames, + private void checkStaticStrategy(final String databaseName, final Map dataSourceMap, final Collection addedWriteDataSourceNames, final Collection 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 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 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 dataSourceMap, + final Collection 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 dataSourceMap, final Collection 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); } } diff --git a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/rule/ReadwriteSplittingRule.java b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/rule/ReadwriteSplittingRule.java index 0ff565ab8d86a..418530c3eb70b 100644 --- a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/rule/ReadwriteSplittingRule.java +++ b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/rule/ReadwriteSplittingRule.java @@ -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)); } } @@ -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 buildReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config, - final Collection 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 createReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config, + final Collection builtRules) { + ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm = loadBalancers.getOrDefault(config.getLoadBalancerName(), ReadQueryLoadBalanceAlgorithmFactory.newInstance()); + return null == config.getStaticStrategy() + ? createDynamicReadwriteSplittingDataSourceRules(config, builtRules, loadBalanceAlgorithm) + : createStaticReadwriteSplittingDataSourceRules(config, builtRules, loadBalanceAlgorithm); } - - private Map buildStaticReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config, - final Collection builtRules, - final ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm) { + + private Map createStaticReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config, + final Collection builtRules, + final ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm) { Map result = new LinkedHashMap<>(); - List readwriteInlineNames = new InlineExpressionParser(config.getName()).splitAndEvaluate(); - List writeInlineDatasourceNames = new InlineExpressionParser(config.getStaticStrategy().getWriteDataSourceName()).splitAndEvaluate(); - List> readInlineDatasourceNames = config.getStaticStrategy().getReadDataSourceNames().stream() + List inlineReadwriteDataSourceNames = new InlineExpressionParser(config.getName()).splitAndEvaluate(); + List inlineWriteDatasourceNames = new InlineExpressionParser(config.getStaticStrategy().getWriteDataSourceName()).splitAndEvaluate(); + List> 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 buildDynamicReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config, - final Collection builtRules, - final ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm) { + + private ReadwriteSplittingDataSourceRuleConfiguration createStaticDataSourceRuleConfiguration(final ReadwriteSplittingDataSourceRuleConfiguration config, final int index, + final List readwriteDataSourceNames, final List writeDatasourceNames, + final List> readDatasourceNames) { + List 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 createDynamicReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config, + final Collection builtRules, + final ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm) { Map result = new LinkedHashMap<>(); - List readwriteInlineNames = new InlineExpressionParser(config.getName()).splitAndEvaluate(); - List 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 inlineReadwriteDataSourceNames = new InlineExpressionParser(config.getName()).splitAndEvaluate(); + List 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 readwriteDataSourceNames, final List autoAwareDataSourceNames) { + return new ReadwriteSplittingDataSourceRuleConfiguration(readwriteDataSourceNames.get(index), null, + new DynamicReadwriteSplittingStrategyConfiguration(autoAwareDataSourceNames.get(index), config.getDynamicStrategy().getWriteDataSourceQueryEnabled()), config.getLoadBalancerName()); + } + /** * Get single data source rule. *