This is an automated email from the ASF dual-hosted git repository.
jianglongtao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 71f4e14a05b Enhanced DistSQL verification of RDL type in storage and
readwrite splitting (#22040)
71f4e14a05b is described below
commit 71f4e14a05b1709edad9a4e1d5bfda683a8de68b
Author: jiangML <[email protected]>
AuthorDate: Thu Nov 10 12:38:50 2022 +0800
Enhanced DistSQL verification of RDL type in storage and readwrite
splitting (#22040)
* Enhanced distsql verification of rdl type in storage unit and
readwrite-splitting
* change resource to storage unit
* change resource to storage unit
---
.../ReadwriteSplittingRuleStatementChecker.java | 149 +++++++++++++++++++--
...lterReadwriteSplittingRuleStatementUpdater.java | 77 +----------
...eateReadwriteSplittingRuleStatementUpdater.java | 87 +-----------
...DropReadwriteSplittingRuleStatementUpdater.java | 15 +--
.../resource/AlterStorageUnitBackendHandler.java | 36 ++---
.../RegisterStorageUnitBackendHandler.java | 20 ++-
.../UnregisterStorageUnitBackendHandler.java | 2 +-
...aultSingleTableStorageUnitStatementUpdater.java | 8 +-
.../RegisterStorageUnitBackendHandlerTest.java | 45 ++++++-
9 files changed, 233 insertions(+), 206 deletions(-)
diff --git
a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/checker/ReadwriteSplittingRuleStatementChecker.java
b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/checker/ReadwriteSplittingRuleStatementChecker.java
index 39d1c84045d..fd4b6fea4e4 100644
---
a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/checker/ReadwriteSplittingRuleStatementChecker.java
+++
b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/checker/ReadwriteSplittingRuleStatementChecker.java
@@ -18,15 +18,30 @@
package org.apache.shardingsphere.readwritesplitting.distsql.handler.checker;
import com.google.common.base.Strings;
+import org.apache.shardingsphere.infra.distsql.constant.ExportableConstants;
+import
org.apache.shardingsphere.infra.distsql.exception.resource.MissingRequiredResourcesException;
+import
org.apache.shardingsphere.infra.distsql.exception.rule.DuplicateRuleException;
+import
org.apache.shardingsphere.infra.distsql.exception.rule.InvalidAlgorithmConfigurationException;
import
org.apache.shardingsphere.infra.distsql.exception.rule.InvalidRuleConfigurationException;
+import
org.apache.shardingsphere.infra.distsql.exception.rule.MissingRequiredRuleException;
+import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import
org.apache.shardingsphere.infra.metadata.database.resource.ShardingSphereResourceMetaData;
+import
org.apache.shardingsphere.infra.rule.identifier.type.exportable.ExportableRule;
+import
org.apache.shardingsphere.infra.rule.identifier.type.exportable.RuleExportEngine;
import
org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
import
org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
import
org.apache.shardingsphere.readwritesplitting.api.rule.ReadwriteSplittingDataSourceRuleConfiguration;
import
org.apache.shardingsphere.readwritesplitting.distsql.parser.segment.ReadwriteSplittingRuleSegment;
+import
org.apache.shardingsphere.readwritesplitting.factory.ReadQueryLoadBalanceAlgorithmFactory;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
import java.util.stream.Collectors;
/**
@@ -35,15 +50,125 @@ import java.util.stream.Collectors;
public final class ReadwriteSplittingRuleStatementChecker {
/**
- * Check duplicate resource names for readwrite-splitting rule statement.
+ * Check create readwrite splitting rule statement.
+ *
+ * @param database database
+ * @param segments segments
+ * @param currentRuleConfig current rule config
+ */
+ public static void checkCreation(final ShardingSphereDatabase database,
final Collection<ReadwriteSplittingRuleSegment> segments, final
ReadwriteSplittingRuleConfiguration currentRuleConfig) {
+ String databaseName = database.getName();
+ checkDuplicateRuleNames(databaseName, segments, currentRuleConfig,
database.getResourceMetaData());
+ checkResourcesExist(databaseName, segments, database);
+ checkDuplicateResourceNames(databaseName, segments, currentRuleConfig,
true);
+ checkLoadBalancers(segments);
+ }
+
+ /**
+ * Check alter readwrite splitting rule statement.
*
- * @param databaseName database name
+ * @param database database
* @param segments segments
* @param currentRuleConfig current rule config
- * @param isCreating whether is creating
*/
- public static void checkDuplicateResourceNames(final String databaseName,
final Collection<ReadwriteSplittingRuleSegment> segments,
- final
ReadwriteSplittingRuleConfiguration currentRuleConfig, final boolean
isCreating) {
+ public static void checkAlteration(final ShardingSphereDatabase database,
final Collection<ReadwriteSplittingRuleSegment> segments, final
ReadwriteSplittingRuleConfiguration currentRuleConfig) {
+ String databaseName = database.getName();
+ checkRuleConfigurationExist(database, currentRuleConfig);
+ checkDuplicateRuleNamesWithSelf(databaseName, segments);
+ checkRuleNamesExist(segments, currentRuleConfig, databaseName);
+ checkResourcesExist(databaseName, segments, database);
+ checkDuplicateResourceNames(databaseName, segments, currentRuleConfig,
false);
+ checkLoadBalancers(segments);
+ }
+
+ /**
+ * Check current rule configuration exist.
+ *
+ * @param database database
+ * @param currentRuleConfig current rule config
+ */
+ public static void checkRuleConfigurationExist(final
ShardingSphereDatabase database, final ReadwriteSplittingRuleConfiguration
currentRuleConfig) {
+ ShardingSpherePreconditions.checkNotNull(currentRuleConfig, () -> new
MissingRequiredRuleException("Readwrite splitting", database.getName()));
+ }
+
+ private static void checkRuleNamesExist(final
Collection<ReadwriteSplittingRuleSegment> segments, final
ReadwriteSplittingRuleConfiguration currentRuleConfig, final String
databaseName) {
+ Collection<String> requiredRuleNames =
segments.stream().map(ReadwriteSplittingRuleSegment::getName).collect(Collectors.toList());
+ Collection<String> currentRuleNames =
currentRuleConfig.getDataSources().stream().map(ReadwriteSplittingDataSourceRuleConfiguration::getName).collect(Collectors.toList());
+ Collection<String> notExistRuleNames =
requiredRuleNames.stream().filter(each ->
!currentRuleNames.contains(each)).collect(Collectors.toSet());
+ ShardingSpherePreconditions.checkState(notExistRuleNames.isEmpty(), ()
-> new MissingRequiredRuleException(databaseName, notExistRuleNames));
+ }
+
+ private static void checkDuplicateRuleNames(final String databaseName,
final Collection<ReadwriteSplittingRuleSegment> segments,
+ final
ReadwriteSplittingRuleConfiguration currentRuleConfig, final
ShardingSphereResourceMetaData resourceMetaData) {
+ checkDuplicateRuleNamesWithSelf(databaseName, segments);
+ checkDuplicateRuleNamesWithResourceMetaData(segments,
resourceMetaData);
+ checkDuplicateRuleNamesWithRuleConfiguration(databaseName, segments,
currentRuleConfig);
+ }
+
+ private static void checkDuplicateRuleNamesWithSelf(final String
databaseName, final Collection<ReadwriteSplittingRuleSegment> segments) {
+ Collection<String> requiredRuleNames =
segments.stream().map(ReadwriteSplittingRuleSegment::getName).collect(Collectors.toList());
+ Collection<String> duplicateRuleNames =
getDuplicate(requiredRuleNames);
+ ShardingSpherePreconditions.checkState(duplicateRuleNames.isEmpty(),
() -> new DuplicateRuleException("Readwrite splitting", databaseName,
duplicateRuleNames));
+ }
+
+ private static Collection<String> getDuplicate(final Collection<String>
require) {
+ return require.stream().collect(Collectors.groupingBy(each -> each,
Collectors.counting())).entrySet().stream()
+ .filter(each -> each.getValue() >
1).map(Map.Entry::getKey).collect(Collectors.toSet());
+ }
+
+ private static void checkDuplicateRuleNamesWithResourceMetaData(final
Collection<ReadwriteSplittingRuleSegment> segments, final
ShardingSphereResourceMetaData resourceMetaData) {
+ Collection<String> currentRuleNames = new LinkedList<>();
+ if (null != resourceMetaData && null !=
resourceMetaData.getDataSources()) {
+
currentRuleNames.addAll(resourceMetaData.getDataSources().keySet());
+ }
+ Collection<String> duplicateRuleNames =
segments.stream().map(ReadwriteSplittingRuleSegment::getName).filter(currentRuleNames::contains).collect(Collectors.toList());
+ ShardingSpherePreconditions.checkState(duplicateRuleNames.isEmpty(),
() -> new InvalidRuleConfigurationException("Readwrite splitting",
duplicateRuleNames,
+ Collections.singleton(String.format("%s already exists in
storage unit", duplicateRuleNames))));
+ }
+
+ private static void checkDuplicateRuleNamesWithRuleConfiguration(final
String databaseName, final Collection<ReadwriteSplittingRuleSegment> segments,
+ final
ReadwriteSplittingRuleConfiguration currentRuleConfig) {
+ Collection<String> currentRuleNames = new LinkedList<>();
+ if (null != currentRuleConfig) {
+
currentRuleNames.addAll(currentRuleConfig.getDataSources().stream().map(ReadwriteSplittingDataSourceRuleConfiguration::getName).collect(Collectors.toList()));
+ }
+ Collection<String> duplicateRuleNames =
segments.stream().map(ReadwriteSplittingRuleSegment::getName).filter(currentRuleNames::contains).collect(Collectors.toList());
+ ShardingSpherePreconditions.checkState(duplicateRuleNames.isEmpty(),
() -> new DuplicateRuleException("Readwrite splitting", databaseName,
duplicateRuleNames));
+ }
+
+ private static void checkResourcesExist(final String databaseName, final
Collection<ReadwriteSplittingRuleSegment> segments, final
ShardingSphereDatabase database) {
+ Collection<String> requireResources = new LinkedHashSet<>();
+ Collection<String> requireDiscoverableResources = new
LinkedHashSet<>();
+ segments.forEach(each -> {
+ if (Strings.isNullOrEmpty(each.getAutoAwareResource())) {
+ requireResources.add(each.getWriteDataSource());
+ requireResources.addAll(each.getReadDataSources());
+ } else {
+ requireDiscoverableResources.add(each.getAutoAwareResource());
+ }
+ });
+ Collection<String> notExistResources =
database.getResourceMetaData().getNotExistedResources(requireResources);
+ ShardingSpherePreconditions.checkState(notExistResources.isEmpty(), ()
-> new MissingRequiredResourcesException(databaseName, notExistResources));
+ Collection<String> logicResources = getLogicResources(database);
+ Collection<String> notExistLogicResources =
requireDiscoverableResources.stream().filter(each ->
!logicResources.contains(each)).collect(Collectors.toSet());
+
ShardingSpherePreconditions.checkState(notExistLogicResources.isEmpty(), () ->
new MissingRequiredResourcesException(databaseName, notExistLogicResources));
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Collection<String> getLogicResources(final
ShardingSphereDatabase database) {
+ Collection<String> result = new LinkedHashSet<>();
+ Optional<ExportableRule> exportableRule =
database.getRuleMetaData().findRules(ExportableRule.class).stream()
+ .filter(each -> new
RuleExportEngine(each).containExportableKey(Collections.singletonList(ExportableConstants.EXPORT_DB_DISCOVERY_PRIMARY_DATA_SOURCES))).findAny();
+ exportableRule.ifPresent(optional -> {
+ Map<String, Object> exportData = new
RuleExportEngine(optional).export(Collections.singletonList(ExportableConstants.EXPORT_DB_DISCOVERY_PRIMARY_DATA_SOURCES));
+ Collection<String> logicResources = ((Map<String, String>)
exportData.getOrDefault(ExportableConstants.EXPORT_DB_DISCOVERY_PRIMARY_DATA_SOURCES,
Collections.emptyMap())).keySet();
+ result.addAll(logicResources);
+ });
+ return result;
+ }
+
+ private static void checkDuplicateResourceNames(final String databaseName,
final Collection<ReadwriteSplittingRuleSegment> segments,
+ final
ReadwriteSplittingRuleConfiguration currentRuleConfig, final boolean
isCreating) {
Collection<String> existedWriteDataSourceNames = new HashSet<>();
Collection<String> existedReadDataSourceNames = new HashSet<>();
if (null != currentRuleConfig) {
@@ -67,8 +192,8 @@ public final class ReadwriteSplittingRuleStatementChecker {
for (final ReadwriteSplittingRuleSegment each : segments) {
if (!Strings.isNullOrEmpty(each.getWriteDataSource())) {
String writeDataSource = each.getWriteDataSource();
-
ShardingSpherePreconditions.checkState(writeDataSourceNames.add(writeDataSource),
() -> new InvalidRuleConfigurationException("readwrite splitting",
each.getName(),
- String.format("Can not config duplicate write resource
`%s` in database `%s`", writeDataSource, databaseName)));
+
ShardingSpherePreconditions.checkState(writeDataSourceNames.add(writeDataSource),
() -> new InvalidRuleConfigurationException("Readwrite splitting",
each.getName(),
+ String.format("Can not config duplicate write storage
unit `%s` in database `%s`", writeDataSource, databaseName)));
}
}
}
@@ -78,10 +203,16 @@ public final class ReadwriteSplittingRuleStatementChecker {
for (ReadwriteSplittingRuleSegment each : segments) {
if (null != each.getReadDataSources()) {
for (String readDataSource : each.getReadDataSources()) {
-
ShardingSpherePreconditions.checkState(readDataSourceNames.add(readDataSource),
() -> new InvalidRuleConfigurationException("readwrite splitting",
each.getName(),
- String.format("Can not config duplicate read
resource `%s` in database `%s`", readDataSource, databaseName)));
+
ShardingSpherePreconditions.checkState(readDataSourceNames.add(readDataSource),
() -> new InvalidRuleConfigurationException("Readwrite splitting",
each.getName(),
+ String.format("Can not config duplicate read
storage unit `%s` in database `%s`", readDataSource, databaseName)));
}
}
}
}
+
+ private static void checkLoadBalancers(final
Collection<ReadwriteSplittingRuleSegment> segments) {
+ Collection<String> notExistedLoadBalancers =
segments.stream().map(ReadwriteSplittingRuleSegment::getLoadBalancer).filter(Objects::nonNull).distinct()
+ .filter(each ->
!ReadQueryLoadBalanceAlgorithmFactory.contains(each)).collect(Collectors.toSet());
+
ShardingSpherePreconditions.checkState(notExistedLoadBalancers.isEmpty(), () ->
new InvalidAlgorithmConfigurationException("Load balancers",
notExistedLoadBalancers));
+ }
}
diff --git
a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingRuleStatementUpdater.java
b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingRuleStatementUpdater.java
index ceafd2be270..ffe64b08ae5 100644
---
a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingRuleStatementUpdater.java
+++
b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/AlterReadwriteSplittingRuleStatementUpdater.java
@@ -18,33 +18,16 @@
package org.apache.shardingsphere.readwritesplitting.distsql.handler.update;
import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
-import org.apache.shardingsphere.infra.distsql.constant.ExportableConstants;
-import
org.apache.shardingsphere.infra.distsql.exception.resource.MissingRequiredResourcesException;
-import
org.apache.shardingsphere.infra.distsql.exception.rule.InvalidAlgorithmConfigurationException;
-import
org.apache.shardingsphere.infra.distsql.exception.rule.MissingRequiredRuleException;
import
org.apache.shardingsphere.infra.distsql.update.RuleDefinitionAlterUpdater;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
-import
org.apache.shardingsphere.infra.rule.identifier.type.exportable.ExportableRule;
-import
org.apache.shardingsphere.infra.rule.identifier.type.exportable.RuleExportEngine;
-import
org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
import
org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
import
org.apache.shardingsphere.readwritesplitting.api.rule.ReadwriteSplittingDataSourceRuleConfiguration;
import
org.apache.shardingsphere.readwritesplitting.distsql.handler.checker.ReadwriteSplittingRuleStatementChecker;
import
org.apache.shardingsphere.readwritesplitting.distsql.handler.converter.ReadwriteSplittingRuleStatementConverter;
-import
org.apache.shardingsphere.readwritesplitting.distsql.parser.segment.ReadwriteSplittingRuleSegment;
import
org.apache.shardingsphere.readwritesplitting.distsql.parser.statement.AlterReadwriteSplittingRuleStatement;
-import
org.apache.shardingsphere.readwritesplitting.factory.ReadQueryLoadBalanceAlgorithmFactory;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Objects;
import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
/**
* Alter readwrite-splitting rule statement updater.
@@ -53,65 +36,7 @@ public final class
AlterReadwriteSplittingRuleStatementUpdater implements RuleDe
@Override
public void checkSQLStatement(final ShardingSphereDatabase database, final
AlterReadwriteSplittingRuleStatement sqlStatement, final
ReadwriteSplittingRuleConfiguration currentRuleConfig) {
- String databaseName = database.getName();
- checkCurrentRuleConfiguration(databaseName, currentRuleConfig);
- checkToBeAlteredRules(databaseName, sqlStatement, currentRuleConfig);
- checkToBeAlteredResources(databaseName, sqlStatement, database);
- // TODO move all check methods to checker
-
ReadwriteSplittingRuleStatementChecker.checkDuplicateResourceNames(databaseName,
sqlStatement.getRules(), currentRuleConfig, false);
- checkToBeAlteredLoadBalancer(sqlStatement);
- }
-
- private void checkCurrentRuleConfiguration(final String databaseName,
final ReadwriteSplittingRuleConfiguration currentRuleConfig) throws
MissingRequiredRuleException {
- ShardingSpherePreconditions.checkNotNull(currentRuleConfig, () -> new
MissingRequiredRuleException("Readwrite splitting", databaseName));
- }
-
- private void checkToBeAlteredRules(final String databaseName, final
AlterReadwriteSplittingRuleStatement sqlStatement,
- final
ReadwriteSplittingRuleConfiguration currentRuleConfig) throws
MissingRequiredRuleException {
- Collection<String> currentRuleNames =
currentRuleConfig.getDataSources().stream().map(ReadwriteSplittingDataSourceRuleConfiguration::getName).collect(Collectors.toSet());
- Collection<String> notExistedRuleNames =
getToBeAlteredRuleNames(sqlStatement).stream().filter(each ->
!currentRuleNames.contains(each)).collect(Collectors.toList());
- ShardingSpherePreconditions.checkState(notExistedRuleNames.isEmpty(),
() -> new MissingRequiredRuleException("Readwrite splitting", databaseName,
notExistedRuleNames));
- }
-
- private Collection<String> getToBeAlteredRuleNames(final
AlterReadwriteSplittingRuleStatement sqlStatement) {
- return
sqlStatement.getRules().stream().map(ReadwriteSplittingRuleSegment::getName).collect(Collectors.toSet());
- }
-
- private void checkToBeAlteredLoadBalancer(final
AlterReadwriteSplittingRuleStatement sqlStatement) throws
InvalidAlgorithmConfigurationException {
- Collection<String> invalidLoadBalancers =
sqlStatement.getRules().stream().map(ReadwriteSplittingRuleSegment::getLoadBalancer).filter(Objects::nonNull).distinct()
- .filter(each ->
!ReadQueryLoadBalanceAlgorithmFactory.contains(each)).collect(Collectors.toList());
- ShardingSpherePreconditions.checkState(invalidLoadBalancers.isEmpty(),
() -> new InvalidAlgorithmConfigurationException("Load balancers",
invalidLoadBalancers));
- }
-
- private void checkToBeAlteredResources(final String databaseName, final
AlterReadwriteSplittingRuleStatement sqlStatement, final ShardingSphereDatabase
database) {
- Collection<String> requireResources = new LinkedHashSet<>();
- Collection<String> requireDiscoverableResources = new
LinkedHashSet<>();
- sqlStatement.getRules().forEach(each -> {
- if (Strings.isNullOrEmpty(each.getAutoAwareResource())) {
- requireResources.add(each.getWriteDataSource());
- requireResources.addAll(each.getReadDataSources());
- } else {
- requireDiscoverableResources.add(each.getAutoAwareResource());
- }
- });
- Collection<String> notExistResources =
database.getResourceMetaData().getNotExistedResources(requireResources);
- ShardingSpherePreconditions.checkState(notExistResources.isEmpty(), ()
-> new MissingRequiredResourcesException(databaseName, notExistResources));
- Collection<String> logicResources = getLogicResources(database);
- Set<String> notExistLogicResources =
requireDiscoverableResources.stream().filter(each ->
!logicResources.contains(each)).collect(Collectors.toSet());
-
ShardingSpherePreconditions.checkState(notExistLogicResources.isEmpty(), () ->
new MissingRequiredResourcesException(databaseName, notExistLogicResources));
- }
-
- @SuppressWarnings("unchecked")
- private Collection<String> getLogicResources(final ShardingSphereDatabase
database) {
- Collection<String> result = new LinkedHashSet<>();
- Optional<ExportableRule> exportableRule =
database.getRuleMetaData().findRules(ExportableRule.class).stream()
- .filter(each -> new
RuleExportEngine(each).containExportableKey(Collections.singletonList(ExportableConstants.EXPORT_DB_DISCOVERY_PRIMARY_DATA_SOURCES))).findAny();
- exportableRule.ifPresent(optional -> {
- Map<String, Object> exportData = new
RuleExportEngine(optional).export(Collections.singletonList(ExportableConstants.EXPORT_DB_DISCOVERY_PRIMARY_DATA_SOURCES));
- Set<String> logicResources = ((Map<String, String>)
exportData.getOrDefault(ExportableConstants.EXPORT_DB_DISCOVERY_PRIMARY_DATA_SOURCES,
Collections.emptyMap())).keySet();
- result.addAll(logicResources);
- });
- return result;
+ ReadwriteSplittingRuleStatementChecker.checkAlteration(database,
sqlStatement.getRules(), currentRuleConfig);
}
@Override
diff --git
a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleStatementUpdater.java
b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleStatementUpdater.java
index e06218a62cf..5e4c8d6483c 100644
---
a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleStatementUpdater.java
+++
b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/CreateReadwriteSplittingRuleStatementUpdater.java
@@ -17,34 +17,12 @@
package org.apache.shardingsphere.readwritesplitting.distsql.handler.update;
-import com.google.common.base.Strings;
-import org.apache.shardingsphere.infra.distsql.constant.ExportableConstants;
-import
org.apache.shardingsphere.infra.distsql.exception.resource.MissingRequiredResourcesException;
-import
org.apache.shardingsphere.infra.distsql.exception.rule.DuplicateRuleException;
-import
org.apache.shardingsphere.infra.distsql.exception.rule.InvalidAlgorithmConfigurationException;
-import
org.apache.shardingsphere.infra.distsql.exception.rule.InvalidRuleConfigurationException;
import
org.apache.shardingsphere.infra.distsql.update.RuleDefinitionCreateUpdater;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
-import
org.apache.shardingsphere.infra.metadata.database.resource.ShardingSphereResourceMetaData;
-import
org.apache.shardingsphere.infra.rule.identifier.type.exportable.ExportableRule;
-import
org.apache.shardingsphere.infra.rule.identifier.type.exportable.RuleExportEngine;
-import
org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
import
org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
-import
org.apache.shardingsphere.readwritesplitting.api.rule.ReadwriteSplittingDataSourceRuleConfiguration;
import
org.apache.shardingsphere.readwritesplitting.distsql.handler.checker.ReadwriteSplittingRuleStatementChecker;
import
org.apache.shardingsphere.readwritesplitting.distsql.handler.converter.ReadwriteSplittingRuleStatementConverter;
-import
org.apache.shardingsphere.readwritesplitting.distsql.parser.segment.ReadwriteSplittingRuleSegment;
import
org.apache.shardingsphere.readwritesplitting.distsql.parser.statement.CreateReadwriteSplittingRuleStatement;
-import
org.apache.shardingsphere.readwritesplitting.factory.ReadQueryLoadBalanceAlgorithmFactory;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.stream.Collectors;
/**
* Create readwrite-splitting rule statement updater.
@@ -53,70 +31,7 @@ public final class
CreateReadwriteSplittingRuleStatementUpdater implements RuleD
@Override
public void checkSQLStatement(final ShardingSphereDatabase database, final
CreateReadwriteSplittingRuleStatement sqlStatement, final
ReadwriteSplittingRuleConfiguration currentRuleConfig) {
- String databaseName = database.getName();
- checkDuplicateRuleNames(databaseName, sqlStatement, currentRuleConfig,
database.getResourceMetaData());
- checkToBeCreatedResources(databaseName, sqlStatement, database);
- // TODO move all check methods to checker
-
ReadwriteSplittingRuleStatementChecker.checkDuplicateResourceNames(databaseName,
sqlStatement.getRules(), currentRuleConfig, true);
- checkToBeCreatedLoadBalancers(sqlStatement);
- }
-
- private void checkDuplicateRuleNames(final String databaseName, final
CreateReadwriteSplittingRuleStatement sqlStatement,
- final
ReadwriteSplittingRuleConfiguration currentRuleConfig, final
ShardingSphereResourceMetaData resourceMetaData) {
- Collection<String> currentRuleNames = new LinkedList<>();
- if (null != resourceMetaData && null !=
resourceMetaData.getDataSources()) {
-
currentRuleNames.addAll(resourceMetaData.getDataSources().keySet());
- }
- Collection<String> duplicateRuleNames =
sqlStatement.getRules().stream().map(ReadwriteSplittingRuleSegment::getName).filter(currentRuleNames::contains).collect(Collectors.toList());
- if (!duplicateRuleNames.isEmpty()) {
- throw new InvalidRuleConfigurationException("readwrite splitting",
duplicateRuleNames, Collections.singleton(String.format("%s already exists in
resource", duplicateRuleNames)));
- }
- if (null != currentRuleConfig) {
-
currentRuleNames.addAll(currentRuleConfig.getDataSources().stream().map(ReadwriteSplittingDataSourceRuleConfiguration::getName).collect(Collectors.toList()));
- }
- duplicateRuleNames =
sqlStatement.getRules().stream().map(ReadwriteSplittingRuleSegment::getName).filter(currentRuleNames::contains).collect(Collectors.toList());
- if (!duplicateRuleNames.isEmpty()) {
- throw new DuplicateRuleException("readwrite splitting",
databaseName, duplicateRuleNames);
- }
- }
-
- private void checkToBeCreatedResources(final String databaseName, final
CreateReadwriteSplittingRuleStatement sqlStatement, final
ShardingSphereDatabase database) {
- Collection<String> requireResources = new LinkedHashSet<>();
- Collection<String> requireDiscoverableResources = new
LinkedHashSet<>();
- sqlStatement.getRules().forEach(each -> {
- if (Strings.isNullOrEmpty(each.getAutoAwareResource())) {
- requireResources.add(each.getWriteDataSource());
- requireResources.addAll(each.getReadDataSources());
- } else {
- requireDiscoverableResources.add(each.getAutoAwareResource());
- }
- });
- Collection<String> notExistResources =
database.getResourceMetaData().getNotExistedResources(requireResources);
- ShardingSpherePreconditions.checkState(notExistResources.isEmpty(), ()
-> new MissingRequiredResourcesException(databaseName, notExistResources));
- Collection<String> logicResources = getLogicResources(database);
- Collection<String> notExistLogicResources =
requireDiscoverableResources.stream().filter(each ->
!logicResources.contains(each)).collect(Collectors.toSet());
-
ShardingSpherePreconditions.checkState(notExistLogicResources.isEmpty(), () ->
new MissingRequiredResourcesException(databaseName, notExistLogicResources));
- }
-
- @SuppressWarnings("unchecked")
- private Collection<String> getLogicResources(final ShardingSphereDatabase
database) {
- Collection<String> result = new LinkedHashSet<>();
- Optional<ExportableRule> exportableRule =
database.getRuleMetaData().findRules(ExportableRule.class).stream()
- .filter(each -> new
RuleExportEngine(each).containExportableKey(Collections.singletonList(ExportableConstants.EXPORT_DB_DISCOVERY_PRIMARY_DATA_SOURCES))).findAny();
- exportableRule.ifPresent(optional -> {
- Map<String, Object> exportData = new
RuleExportEngine(optional).export(Collections.singletonList(ExportableConstants.EXPORT_DB_DISCOVERY_PRIMARY_DATA_SOURCES));
- Collection<String> logicResources = ((Map<String, String>)
exportData.getOrDefault(ExportableConstants.EXPORT_DB_DISCOVERY_PRIMARY_DATA_SOURCES,
Collections.emptyMap())).keySet();
- result.addAll(logicResources);
- });
- return result;
- }
-
- private void checkToBeCreatedLoadBalancers(final
CreateReadwriteSplittingRuleStatement sqlStatement) throws
InvalidAlgorithmConfigurationException {
- Collection<String> notExistedLoadBalancers =
sqlStatement.getRules().stream().map(ReadwriteSplittingRuleSegment::getLoadBalancer).filter(Objects::nonNull).distinct()
- .filter(each ->
!ReadQueryLoadBalanceAlgorithmFactory.contains(each)).collect(Collectors.toList());
- if (!notExistedLoadBalancers.isEmpty()) {
- throw new InvalidAlgorithmConfigurationException("Load balancers",
notExistedLoadBalancers);
- }
+ ReadwriteSplittingRuleStatementChecker.checkCreation(database,
sqlStatement.getRules(), currentRuleConfig);
}
@Override
diff --git
a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/DropReadwriteSplittingRuleStatementUpdater.java
b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/DropReadwriteSplittingRuleStatementUpdater.java
index eba9bacf644..643be82232d 100644
---
a/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/DropReadwriteSplittingRuleStatementUpdater.java
+++
b/features/readwrite-splitting/distsql/handler/src/main/java/org/apache/shardingsphere/readwritesplitting/distsql/handler/update/DropReadwriteSplittingRuleStatementUpdater.java
@@ -28,6 +28,7 @@ import
org.apache.shardingsphere.infra.rule.identifier.type.DataSourceContainedR
import
org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
import
org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
import
org.apache.shardingsphere.readwritesplitting.api.rule.ReadwriteSplittingDataSourceRuleConfiguration;
+import
org.apache.shardingsphere.readwritesplitting.distsql.handler.checker.ReadwriteSplittingRuleStatementChecker;
import
org.apache.shardingsphere.readwritesplitting.distsql.parser.statement.DropReadwriteSplittingRuleStatement;
import
org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingRule;
@@ -49,15 +50,11 @@ public final class
DropReadwriteSplittingRuleStatementUpdater implements RuleDef
return;
}
String databaseName = database.getName();
- checkCurrentRuleConfiguration(databaseName, currentRuleConfig);
+
ReadwriteSplittingRuleStatementChecker.checkRuleConfigurationExist(database,
currentRuleConfig);
checkToBeDroppedRuleNames(databaseName, sqlStatement,
currentRuleConfig);
checkToBeDroppedInUsed(database, sqlStatement);
}
- private void checkCurrentRuleConfiguration(final String databaseName,
final ReadwriteSplittingRuleConfiguration currentRuleConfig) throws
MissingRequiredRuleException {
- ShardingSpherePreconditions.checkNotNull(currentRuleConfig, () -> new
MissingRequiredRuleException("Readwrite splitting", databaseName));
- }
-
private void checkToBeDroppedRuleNames(final String databaseName, final
DropReadwriteSplittingRuleStatement sqlStatement,
final
ReadwriteSplittingRuleConfiguration currentRuleConfig) throws
MissingRequiredRuleException {
if (sqlStatement.isIfExists()) {
@@ -65,17 +62,13 @@ public final class
DropReadwriteSplittingRuleStatementUpdater implements RuleDef
}
Collection<String> currentRuleNames =
currentRuleConfig.getDataSources().stream().map(ReadwriteSplittingDataSourceRuleConfiguration::getName).collect(Collectors.toList());
Collection<String> notExistedRuleNames =
sqlStatement.getRuleNames().stream().filter(each ->
!currentRuleNames.contains(each)).collect(Collectors.toList());
- if (!notExistedRuleNames.isEmpty()) {
- throw new MissingRequiredRuleException("Readwrite splitting",
databaseName, sqlStatement.getRuleNames());
- }
+ ShardingSpherePreconditions.checkState(notExistedRuleNames.isEmpty(),
() -> new MissingRequiredRuleException("Readwrite splitting", databaseName,
sqlStatement.getRuleNames()));
}
private void checkToBeDroppedInUsed(final ShardingSphereDatabase database,
final DropReadwriteSplittingRuleStatement sqlStatement) throws
RuleInUsedException {
Collection<String> resourceBeUsed = getInUsedResources(database);
Collection<String> ruleInUsed =
sqlStatement.getRuleNames().stream().filter(resourceBeUsed::contains).collect(Collectors.toSet());
- if (!ruleInUsed.isEmpty()) {
- throw new RuleInUsedException("Readwrite splitting",
database.getName(), ruleInUsed);
- }
+ ShardingSpherePreconditions.checkState(ruleInUsed.isEmpty(), () -> new
RuleInUsedException("Readwrite splitting", database.getName(), ruleInUsed));
}
private Collection<String> getInUsedResources(final ShardingSphereDatabase
database) {
diff --git
a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitBackendHandler.java
b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitBackendHandler.java
index b6816e21759..468e47ea435 100644
---
a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitBackendHandler.java
+++
b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitBackendHandler.java
@@ -46,6 +46,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Objects;
import java.util.stream.Collectors;
/**
@@ -72,43 +73,43 @@ public final class AlterStorageUnitBackendHandler extends
DatabaseRequiredBacken
try {
ProxyContext.getInstance().getContextManager().updateResources(databaseName,
dataSourcePropsMap);
} catch (final SQLException | ShardingSphereServerException ex) {
- log.error("Alter resource failed", ex);
+ log.error("Alter storage unit failed", ex);
throw new
InvalidResourcesException(Collections.singleton(ex.getMessage()));
}
return new UpdateResponseHeader(sqlStatement);
}
private void checkSQLStatement(final String databaseName, final
AlterStorageUnitStatement sqlStatement) {
- Collection<String> toBeAlteredResourceNames =
getToBeAlteredResourceNames(sqlStatement);
- checkToBeAlteredDuplicateResourceNames(toBeAlteredResourceNames);
- checkResourceNameExisted(databaseName, toBeAlteredResourceNames);
+ Collection<String> toBeAlteredStorageUnitNames =
getToBeAlteredStorageUnitNames(sqlStatement);
+ checkToBeAlteredDuplicateStorageUnitNames(toBeAlteredStorageUnitNames);
+ checkStorageUnitNameExisted(databaseName, toBeAlteredStorageUnitNames);
checkDatabase(databaseName, sqlStatement);
}
private void checkDatabase(final String databaseName, final
AlterStorageUnitStatement sqlStatement) {
- Map<String, DataSource> resources =
ProxyContext.getInstance().getDatabase(databaseName).getResourceMetaData().getDataSources();
+ Map<String, DataSource> storageUnits =
ProxyContext.getInstance().getDatabase(databaseName).getResourceMetaData().getDataSources();
Collection<String> invalid =
sqlStatement.getDataSources().stream().collect(Collectors.toMap(DataSourceSegment::getName,
each -> each)).entrySet().stream()
- .filter(each -> !isIdenticalDatabase(each.getValue(),
resources.get(each.getKey()))).map(Entry::getKey).collect(Collectors.toSet());
+ .filter(each -> !isIdenticalDatabase(each.getValue(),
storageUnits.get(each.getKey()))).map(Entry::getKey).collect(Collectors.toSet());
ShardingSpherePreconditions.checkState(invalid.isEmpty(), () -> new
InvalidResourcesException(Collections.singleton(String.format("Cannot alter the
database of %s", invalid))));
}
- private Collection<String> getToBeAlteredResourceNames(final
AlterStorageUnitStatement sqlStatement) {
+ private Collection<String> getToBeAlteredStorageUnitNames(final
AlterStorageUnitStatement sqlStatement) {
return
sqlStatement.getDataSources().stream().map(DataSourceSegment::getName).collect(Collectors.toList());
}
- private void checkToBeAlteredDuplicateResourceNames(final
Collection<String> resourceNames) {
- Collection<String> duplicateResourceNames =
getDuplicateResourceNames(resourceNames);
-
ShardingSpherePreconditions.checkState(duplicateResourceNames.isEmpty(), () ->
new DuplicateResourceException(duplicateResourceNames));
+ private void checkToBeAlteredDuplicateStorageUnitNames(final
Collection<String> storageUnitNames) {
+ Collection<String> duplicateStorageUnitNames =
getDuplicateStorageUnitNames(storageUnitNames);
+
ShardingSpherePreconditions.checkState(duplicateStorageUnitNames.isEmpty(), ()
-> new DuplicateResourceException(duplicateStorageUnitNames));
}
- private Collection<String> getDuplicateResourceNames(final
Collection<String> resourceNames) {
- return resourceNames.stream().filter(each ->
resourceNames.stream().filter(each::equals).count() >
1).collect(Collectors.toList());
+ private Collection<String> getDuplicateStorageUnitNames(final
Collection<String> storageUnitNames) {
+ return storageUnitNames.stream().filter(each ->
storageUnitNames.stream().filter(each::equals).count() >
1).collect(Collectors.toList());
}
- private void checkResourceNameExisted(final String databaseName, final
Collection<String> resourceNames) {
- Map<String, DataSource> resources =
ProxyContext.getInstance().getDatabase(databaseName).getResourceMetaData().getDataSources();
- Collection<String> notExistedResourceNames =
resourceNames.stream().filter(each ->
!resources.containsKey(each)).collect(Collectors.toList());
-
ShardingSpherePreconditions.checkState(notExistedResourceNames.isEmpty(), () ->
new MissingRequiredResourcesException(databaseName, notExistedResourceNames));
+ private void checkStorageUnitNameExisted(final String databaseName, final
Collection<String> storageUnitNames) {
+ Map<String, DataSource> storageUnits =
ProxyContext.getInstance().getDatabase(databaseName).getResourceMetaData().getDataSources();
+ Collection<String> notExistedStorageUnitNames =
storageUnitNames.stream().filter(each ->
!storageUnits.containsKey(each)).collect(Collectors.toList());
+
ShardingSpherePreconditions.checkState(notExistedStorageUnitNames.isEmpty(), ()
-> new MissingRequiredResourcesException(databaseName,
notExistedStorageUnitNames));
}
private boolean isIdenticalDatabase(final DataSourceSegment segment, final
DataSource dataSource) {
@@ -128,6 +129,7 @@ public final class AlterStorageUnitBackendHandler extends
DatabaseRequiredBacken
}
String url =
String.valueOf(DataSourcePropertiesCreator.create(dataSource).getConnectionPropertySynonyms().getStandardProperties().get("url"));
JdbcUrl dataSourceJdbcUrl = new StandardJdbcUrlParser().parse(url);
- return hostName.equals(dataSourceJdbcUrl.getHostname()) &&
port.equals(String.valueOf(dataSourceJdbcUrl.getPort())) &&
database.equals(dataSourceJdbcUrl.getDatabase());
+ return Objects.equals(hostName, dataSourceJdbcUrl.getHostname()) &&
Objects.equals(port, String.valueOf(dataSourceJdbcUrl.getPort()))
+ && Objects.equals(database, dataSourceJdbcUrl.getDatabase());
}
}
diff --git
a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandler.java
b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandler.java
index f2279b4dc3b..13be0fc6d7d 100644
---
a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandler.java
+++
b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandler.java
@@ -32,6 +32,9 @@ import
org.apache.shardingsphere.proxy.backend.handler.DatabaseRequiredBackendHa
import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
import
org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResponseHeader;
import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
+import
org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
+import
org.apache.shardingsphere.readwritesplitting.api.rule.ReadwriteSplittingDataSourceRuleConfiguration;
+import
org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingRule;
import
org.apache.shardingsphere.sharding.distsql.handler.converter.ResourceSegmentsConverter;
import java.sql.SQLException;
@@ -40,6 +43,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
/**
* Register storage unit backend handler.
@@ -65,7 +70,7 @@ public final class RegisterStorageUnitBackendHandler extends
DatabaseRequiredBac
try {
ProxyContext.getInstance().getContextManager().addResources(databaseName,
dataSourcePropsMap);
} catch (final SQLException | ShardingSphereServerException ex) {
- log.error("Add resource failed", ex);
+ log.error("Register storage unit failed", ex);
throw new
InvalidResourcesException(Collections.singleton(ex.getMessage()));
}
return new UpdateResponseHeader(sqlStatement);
@@ -81,5 +86,18 @@ public final class RegisterStorageUnitBackendHandler extends
DatabaseRequiredBac
dataSourceNames.add(each.getName());
}
ShardingSpherePreconditions.checkState(duplicateDataSourceNames.isEmpty(), ()
-> new DuplicateResourceException(duplicateDataSourceNames));
+ checkDuplicateDataSourceNameWithReadwriteSplittingRule(databaseName,
dataSourceNames);
+ }
+
+ private void checkDuplicateDataSourceNameWithReadwriteSplittingRule(final
String databaseName, final Collection<String> requiredDataSourceNames) {
+ Optional<ReadwriteSplittingRule> readwriteSplittingRule =
ProxyContext.getInstance().getDatabase(databaseName).getRuleMetaData().findSingleRule(ReadwriteSplittingRule.class);
+ if (!readwriteSplittingRule.isPresent()) {
+ return;
+ }
+ ReadwriteSplittingRuleConfiguration config =
(ReadwriteSplittingRuleConfiguration)
readwriteSplittingRule.get().getConfiguration();
+ Collection<String> existRuleNames =
config.getDataSources().stream().map(ReadwriteSplittingDataSourceRuleConfiguration::getName).collect(Collectors.toSet());
+ Collection<String> duplicateDataSourceNames =
requiredDataSourceNames.stream().filter(each ->
existRuleNames.contains(each)).collect(Collectors.toSet());
+
ShardingSpherePreconditions.checkState(duplicateDataSourceNames.isEmpty(),
+ () -> new
InvalidResourcesException(Collections.singleton(String.format("%s already
exists in readwrite splitting", duplicateDataSourceNames))));
}
}
diff --git
a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitBackendHandler.java
b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitBackendHandler.java
index 7b6658b7a6d..063a2c456d3 100644
---
a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitBackendHandler.java
+++
b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitBackendHandler.java
@@ -62,7 +62,7 @@ public final class UnregisterStorageUnitBackendHandler
extends DatabaseRequiredB
try {
ProxyContext.getInstance().getContextManager().dropResources(databaseName,
toBeDroppedResourceNames);
} catch (final SQLException | ShardingSphereServerException ex) {
- log.error("Drop resource failed", ex);
+ log.error("Unregister storage unit failed", ex);
throw new
InvalidResourcesException(Collections.singleton(ex.getMessage()));
}
return new UpdateResponseHeader(sqlStatement);
diff --git
a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/rule/SetDefaultSingleTableStorageUnitStatementUpdater.java
b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/rule/SetDefaultSingleTableStorageUnitStatementUpdater.java
index 8a64e7ed5a1..c0ff141a77f 100644
---
a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/rule/SetDefaultSingleTableStorageUnitStatementUpdater.java
+++
b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/rule/SetDefaultSingleTableStorageUnitStatementUpdater.java
@@ -35,13 +35,13 @@ public final class
SetDefaultSingleTableStorageUnitStatementUpdater implements R
@Override
public void checkSQLStatement(final ShardingSphereDatabase database, final
SetDefaultSingleTableStorageUnitStatement sqlStatement, final
SingleTableRuleConfiguration currentRuleConfig) {
- checkResourceExist(database, sqlStatement);
+ checkStorageUnitExist(database, sqlStatement);
}
- private void checkResourceExist(final ShardingSphereDatabase database,
final SetDefaultSingleTableStorageUnitStatement sqlStatement) {
+ private void checkStorageUnitExist(final ShardingSphereDatabase database,
final SetDefaultSingleTableStorageUnitStatement sqlStatement) {
if (StringUtils.isNotBlank(sqlStatement.getDefaultStorageUnit())) {
- Collection<String> resourceNames =
database.getResourceMetaData().getDataSources().keySet();
-
ShardingSpherePreconditions.checkState(resourceNames.contains(sqlStatement.getDefaultStorageUnit()),
+ Collection<String> storageUnitNames =
database.getResourceMetaData().getDataSources().keySet();
+
ShardingSpherePreconditions.checkState(storageUnitNames.contains(sqlStatement.getDefaultStorageUnit()),
() -> new
MissingRequiredResourcesException(database.getName(),
Collections.singleton(sqlStatement.getDefaultStorageUnit())));
}
}
diff --git
a/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandlerTest.java
b/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandlerTest.java
index cc6c26e1252..24208a7ccd6 100644
---
a/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandlerTest.java
+++
b/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandlerTest.java
@@ -24,8 +24,10 @@ import
org.apache.shardingsphere.distsql.parser.statement.rdl.create.RegisterSto
import org.apache.shardingsphere.infra.database.type.dialect.MySQLDatabaseType;
import
org.apache.shardingsphere.infra.datasource.props.DataSourcePropertiesValidator;
import
org.apache.shardingsphere.infra.distsql.exception.resource.DuplicateResourceException;
+import
org.apache.shardingsphere.infra.distsql.exception.resource.InvalidResourcesException;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import
org.apache.shardingsphere.infra.metadata.database.resource.ShardingSphereResourceMetaData;
+import
org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRuleMetaData;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
@@ -33,6 +35,9 @@ import
org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
import
org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResponseHeader;
import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
import org.apache.shardingsphere.proxy.backend.util.ProxyContextRestorer;
+import
org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
+import
org.apache.shardingsphere.readwritesplitting.api.rule.ReadwriteSplittingDataSourceRuleConfiguration;
+import
org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingRule;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -44,6 +49,7 @@ import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
+import java.util.Optional;
import java.util.Properties;
import static org.hamcrest.CoreMatchers.instanceOf;
@@ -73,6 +79,12 @@ public final class RegisterStorageUnitBackendHandlerTest
extends ProxyContextRes
@Mock
private ShardingSphereResourceMetaData resourceMetaData;
+ @Mock
+ private ShardingSphereRuleMetaData ruleMetaData;
+
+ @Mock
+ private ReadwriteSplittingRule readwriteSplittingRule;
+
private RegisterStorageUnitBackendHandler
registerStorageUnitBackendHandler;
@Before
@@ -80,6 +92,8 @@ public final class RegisterStorageUnitBackendHandlerTest
extends ProxyContextRes
when(metaDataContexts.getMetaData().getDatabase("test_db")).thenReturn(database);
when(metaDataContexts.getMetaData().containsDatabase("test_db")).thenReturn(true);
when(connectionSession.getProtocolType()).thenReturn(new
MySQLDatabaseType());
+ when(database.getRuleMetaData()).thenReturn(ruleMetaData);
+
when(ruleMetaData.findSingleRule(ReadwriteSplittingRule.class)).thenReturn(Optional.of(readwriteSplittingRule));
registerStorageUnitBackendHandler = new
RegisterStorageUnitBackendHandler(registerStorageUnitStatement,
connectionSession);
Field field =
registerStorageUnitBackendHandler.getClass().getDeclaredField("validator");
field.setAccessible(true);
@@ -94,12 +108,13 @@ public final class RegisterStorageUnitBackendHandlerTest
extends ProxyContextRes
when(metaDataContexts.getMetaData().getDatabases()).thenReturn(Collections.singletonMap("test_db",
database));
when(database.getResourceMetaData()).thenReturn(resourceMetaData);
when(resourceMetaData.getDataSources()).thenReturn(Collections.emptyMap());
+
when(readwriteSplittingRule.getConfiguration()).thenReturn(createReadwriteSplittingRuleConfiguration("read_write"));
ResponseHeader responseHeader =
registerStorageUnitBackendHandler.execute("test_db",
createRegisterStorageUnitStatement());
assertThat(responseHeader, instanceOf(UpdateResponseHeader.class));
}
@Test(expected = DuplicateResourceException.class)
- public void assertExecuteWithDuplicateStorageUnitNames() {
+ public void assertExecuteWithDuplicateStorageUnitNamesInStatement() {
ContextManager contextManager = mock(ContextManager.class,
RETURNS_DEEP_STUBS);
when(contextManager.getMetaDataContexts()).thenReturn(metaDataContexts);
ProxyContext.init(contextManager);
@@ -109,6 +124,34 @@ public final class RegisterStorageUnitBackendHandlerTest
extends ProxyContextRes
registerStorageUnitBackendHandler.execute("test_db",
createRegisterStorageUnitStatementWithDuplicateStorageUnitNames());
}
+ @Test(expected = DuplicateResourceException.class)
+ public void
assertExecuteWithDuplicateStorageUnitNamesWithResourceMetaData() {
+ ContextManager contextManager = mock(ContextManager.class,
RETURNS_DEEP_STUBS);
+
when(contextManager.getMetaDataContexts()).thenReturn(metaDataContexts);
+ ProxyContext.init(contextManager);
+
when(metaDataContexts.getMetaData().getDatabases()).thenReturn(Collections.singletonMap("test_db",
database));
+ when(database.getResourceMetaData()).thenReturn(resourceMetaData);
+
when(resourceMetaData.getDataSources()).thenReturn(Collections.singletonMap("ds_0",
null));
+ registerStorageUnitBackendHandler.execute("test_db",
createRegisterStorageUnitStatement());
+ }
+
+ @Test(expected = InvalidResourcesException.class)
+ public void
assertExecuteWithDuplicateStorageUnitNamesWithReadwriteSplittingRule() {
+ ContextManager contextManager = mock(ContextManager.class,
RETURNS_DEEP_STUBS);
+
when(contextManager.getMetaDataContexts()).thenReturn(metaDataContexts);
+ ProxyContext.init(contextManager);
+
when(metaDataContexts.getMetaData().getDatabases()).thenReturn(Collections.singletonMap("test_db",
database));
+ when(database.getResourceMetaData()).thenReturn(resourceMetaData);
+
when(resourceMetaData.getDataSources()).thenReturn(Collections.emptyMap());
+
when(readwriteSplittingRule.getConfiguration()).thenReturn(createReadwriteSplittingRuleConfiguration("ds_0"));
+ registerStorageUnitBackendHandler.execute("test_db",
createRegisterStorageUnitStatement());
+ }
+
+ private ReadwriteSplittingRuleConfiguration
createReadwriteSplittingRuleConfiguration(final String ruleName) {
+ ReadwriteSplittingDataSourceRuleConfiguration configuration = new
ReadwriteSplittingDataSourceRuleConfiguration(ruleName, null, null, null);
+ return new
ReadwriteSplittingRuleConfiguration(Collections.singleton(configuration),
Collections.emptyMap());
+ }
+
private RegisterStorageUnitStatement createRegisterStorageUnitStatement() {
return new RegisterStorageUnitStatement(Collections.singleton(new
URLBasedDataSourceSegment("ds_0", "jdbc:mysql://127.0.0.1:3306/test0", "root",
"", new Properties())));
}