diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java index 6895ead1d7d72..2dd7436403f62 100644 --- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java +++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/ShardingRule.java @@ -49,7 +49,7 @@ import org.apache.shardingsphere.sharding.api.sharding.ShardingAutoTableAlgorithm; import org.apache.shardingsphere.sharding.cache.ShardingCache; import org.apache.shardingsphere.sharding.exception.algorithm.keygen.GenerateKeyStrategyNotFoundException; -import org.apache.shardingsphere.sharding.exception.algorithm.sharding.ShardingAlgorithmClassImplementationException; +import org.apache.shardingsphere.sharding.exception.algorithm.sharding.ShardingAlgorithmInitializationException; import org.apache.shardingsphere.sharding.exception.metadata.InvalidBindingTablesException; import org.apache.shardingsphere.sharding.exception.metadata.ShardingTableRuleNotFoundException; import org.apache.shardingsphere.sharding.spi.KeyGenerateAlgorithm; @@ -128,8 +128,8 @@ public ShardingRule(final ShardingRuleConfiguration ruleConfig, final Collection tableRules.putAll(createTableRules(ruleConfig.getTables(), ruleConfig.getDefaultKeyGenerateStrategy())); tableRules.putAll(createAutoTableRules(ruleConfig.getAutoTables(), ruleConfig.getDefaultKeyGenerateStrategy())); bindingTableRules.putAll(createBindingTableRules(ruleConfig.getBindingTableGroups())); - defaultDatabaseShardingStrategyConfig = null == ruleConfig.getDefaultDatabaseShardingStrategy() ? new NoneShardingStrategyConfiguration() : ruleConfig.getDefaultDatabaseShardingStrategy(); - defaultTableShardingStrategyConfig = null == ruleConfig.getDefaultTableShardingStrategy() ? new NoneShardingStrategyConfiguration() : ruleConfig.getDefaultTableShardingStrategy(); + defaultDatabaseShardingStrategyConfig = createDefaultDatabaseShardingStrategyConfig(ruleConfig); + defaultTableShardingStrategyConfig = createDefaultTableShardingStrategyConfig(ruleConfig); defaultAuditStrategy = null == ruleConfig.getDefaultAuditStrategy() ? new ShardingAuditStrategyConfiguration(Collections.emptyList(), true) : ruleConfig.getDefaultAuditStrategy(); defaultKeyGenerateAlgorithm = null == ruleConfig.getDefaultKeyGenerateStrategy() ? TypedSPILoader.getService(KeyGenerateAlgorithm.class, null) @@ -148,6 +148,16 @@ public ShardingRule(final ShardingRuleConfiguration ruleConfig, final Collection actualTableMapper = createActualTableMapper(); } + private ShardingStrategyConfiguration createDefaultDatabaseShardingStrategyConfig(final ShardingRuleConfiguration ruleConfig) { + Optional.ofNullable(ruleConfig.getDefaultDatabaseShardingStrategy()).ifPresent(optional -> checkManualShardingAlgorithm(optional.getShardingAlgorithmName(), "default")); + return null == ruleConfig.getDefaultDatabaseShardingStrategy() ? new NoneShardingStrategyConfiguration() : ruleConfig.getDefaultDatabaseShardingStrategy(); + } + + private ShardingStrategyConfiguration createDefaultTableShardingStrategyConfig(final ShardingRuleConfiguration ruleConfig) { + Optional.ofNullable(ruleConfig.getDefaultTableShardingStrategy()).ifPresent(optional -> checkManualShardingAlgorithm(optional.getShardingAlgorithmName(), "default")); + return null == ruleConfig.getDefaultTableShardingStrategy() ? new NoneShardingStrategyConfiguration() : ruleConfig.getDefaultTableShardingStrategy(); + } + private TableNamesMapper createLogicalTableMapper() { TableNamesMapper result = new TableNamesMapper(); tableRules.values().forEach(each -> result.put(each.getLogicTable())); @@ -197,10 +207,22 @@ private Collection getDataSourceNames(final ShardingTableRuleConfigurati } private Map createTableRules(final Collection tableRuleConfigs, final KeyGenerateStrategyConfiguration defaultKeyGenerateStrategyConfig) { - return tableRuleConfigs.stream().map(each -> new TableRule(each, dataSourceNames, getDefaultGenerateKeyColumn(defaultKeyGenerateStrategyConfig))) + return tableRuleConfigs.stream().map(each -> createTableRule(each, defaultKeyGenerateStrategyConfig)) .collect(Collectors.toMap(each -> each.getLogicTable().toLowerCase(), Function.identity(), (oldValue, currentValue) -> oldValue, LinkedHashMap::new)); } + private TableRule createTableRule(final ShardingTableRuleConfiguration tableRuleConfig, final KeyGenerateStrategyConfiguration defaultKeyGenerateStrategyConfig) { + Optional.ofNullable(tableRuleConfig.getDatabaseShardingStrategy()).ifPresent(optional -> checkManualShardingAlgorithm(optional.getShardingAlgorithmName(), tableRuleConfig.getLogicTable())); + Optional.ofNullable(tableRuleConfig.getTableShardingStrategy()).ifPresent(optional -> checkManualShardingAlgorithm(optional.getShardingAlgorithmName(), tableRuleConfig.getLogicTable())); + return new TableRule(tableRuleConfig, dataSourceNames, getDefaultGenerateKeyColumn(defaultKeyGenerateStrategyConfig)); + } + + private void checkManualShardingAlgorithm(final String shardingAlgorithmName, final String logicTable) { + ShardingAlgorithm shardingAlgorithm = shardingAlgorithms.get(shardingAlgorithmName); + ShardingSpherePreconditions.checkState(!(shardingAlgorithm instanceof ShardingAutoTableAlgorithm), + () -> new ShardingAlgorithmInitializationException(shardingAlgorithm.getType(), String.format("`%s` tables sharding configuration can not use auto sharding algorithm.", logicTable))); + } + private Map createAutoTableRules(final Collection autoTableRuleConfigs, final KeyGenerateStrategyConfiguration defaultKeyGenerateStrategyConfig) { return autoTableRuleConfigs.stream().map(each -> createAutoTableRule(defaultKeyGenerateStrategyConfig, each)) @@ -208,12 +230,17 @@ private Map createAutoTableRules(final Collection new ShardingAlgorithmClassImplementationException(autoTableRuleConfig.getShardingStrategy().getShardingAlgorithmName(), ShardingAutoTableAlgorithm.class)); return new TableRule(autoTableRuleConfig, dataSourceNames, (ShardingAutoTableAlgorithm) shardingAlgorithm, getDefaultGenerateKeyColumn(defaultKeyGenerateStrategyConfig)); } + private void checkAutoShardingAlgorithm(final String shardingAlgorithmName, final String logicTable) { + ShardingAlgorithm shardingAlgorithm = shardingAlgorithms.get(shardingAlgorithmName); + ShardingSpherePreconditions.checkState(shardingAlgorithm instanceof ShardingAutoTableAlgorithm, + () -> new ShardingAlgorithmInitializationException(shardingAlgorithm.getType(), String.format("`%s` autoTables sharding configuration must use auto sharding algorithm.", logicTable))); + } + private String getDefaultGenerateKeyColumn(final KeyGenerateStrategyConfiguration defaultKeyGenerateStrategyConfig) { return Optional.ofNullable(defaultKeyGenerateStrategyConfig).map(KeyGenerateStrategyConfiguration::getColumn).orElse(null); } diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/cache/checker/ShardingRouteCacheableCheckerTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/cache/checker/ShardingRouteCacheableCheckerTest.java index 0572ad8b5f850..0b476cc79b46c 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/cache/checker/ShardingRouteCacheableCheckerTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/cache/checker/ShardingRouteCacheableCheckerTest.java @@ -36,6 +36,7 @@ import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration; import org.apache.shardingsphere.sharding.api.config.cache.ShardingCacheConfiguration; import org.apache.shardingsphere.sharding.api.config.cache.ShardingCacheOptionsConfiguration; +import org.apache.shardingsphere.sharding.api.config.rule.ShardingAutoTableRuleConfiguration; import org.apache.shardingsphere.sharding.api.config.rule.ShardingTableReferenceRuleConfiguration; import org.apache.shardingsphere.sharding.api.config.rule.ShardingTableRuleConfiguration; import org.apache.shardingsphere.sharding.api.config.strategy.sharding.StandardShardingStrategyConfiguration; @@ -87,10 +88,10 @@ private ShardingRule createShardingRule() { ruleConfig.getBindingTableGroups().add(new ShardingTableReferenceRuleConfiguration("foo", "t_order,t_order_item")); ruleConfig.getShardingAlgorithms().put("mod", new AlgorithmConfiguration("MOD", PropertiesBuilder.build(new Property("sharding-count", "2")))); ruleConfig.getShardingAlgorithms().put("inline", new AlgorithmConfiguration("INLINE", PropertiesBuilder.build(new Property("algorithm-expression", "ds_${id % 2}")))); - ruleConfig.setDefaultDatabaseShardingStrategy(new StandardShardingStrategyConfiguration("warehouse_id", "mod")); - ShardingTableRuleConfiguration warehouse = new ShardingTableRuleConfiguration("t_warehouse", "ds_${0..1}.t_warehouse"); - warehouse.setDatabaseShardingStrategy(new StandardShardingStrategyConfiguration("id", "mod")); - ruleConfig.getTables().add(warehouse); + ruleConfig.setDefaultDatabaseShardingStrategy(new StandardShardingStrategyConfiguration("warehouse_id", "inline")); + ShardingAutoTableRuleConfiguration warehouse = new ShardingAutoTableRuleConfiguration("t_warehouse", "ds_${0..1}"); + warehouse.setShardingStrategy(new StandardShardingStrategyConfiguration("id", "mod")); + ruleConfig.getAutoTables().add(warehouse); ruleConfig.getTables().add(new ShardingTableRuleConfiguration("t_order", "ds_${0..1}.t_order")); ruleConfig.getTables().add(new ShardingTableRuleConfiguration("t_order_item", "ds_${0..1}.t_order_item")); ShardingTableRuleConfiguration nonCacheableDatabaseSharding = new ShardingTableRuleConfiguration("t_non_cacheable_database_sharding", "ds_${0..1}.t_non_cacheable_database_sharding"); diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingRuleTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingRuleTest.java index 7060d9237a842..ed9ba2c91a6c1 100644 --- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingRuleTest.java +++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/rule/ShardingRuleTest.java @@ -43,6 +43,7 @@ import org.apache.shardingsphere.sharding.api.config.strategy.sharding.ShardingStrategyConfiguration; import org.apache.shardingsphere.sharding.api.config.strategy.sharding.StandardShardingStrategyConfiguration; import org.apache.shardingsphere.sharding.exception.algorithm.keygen.GenerateKeyStrategyNotFoundException; +import org.apache.shardingsphere.sharding.exception.algorithm.sharding.ShardingAlgorithmInitializationException; import org.apache.shardingsphere.sharding.exception.metadata.InvalidBindingTablesException; import org.apache.shardingsphere.sharding.exception.metadata.ShardingTableRuleNotFoundException; import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment; @@ -109,6 +110,52 @@ void assertNewShardingRuleWithMinimumConfiguration() { assertNull(actual.getDefaultShardingColumn()); } + @Test + void assertNewShardingRuleWithWrongShardingAlgorithmInDefaultDatabaseShardingStrategy() { + ShardingRuleConfiguration ruleConfig = new ShardingRuleConfiguration(); + ruleConfig.setDefaultDatabaseShardingStrategy(new StandardShardingStrategyConfiguration("order_id", "MOD")); + ruleConfig.getShardingAlgorithms().put("MOD", new AlgorithmConfiguration("MOD", PropertiesBuilder.build(new Property("sharding-count", "2")))); + assertThrows(ShardingAlgorithmInitializationException.class, () -> new ShardingRule(ruleConfig, Collections.emptyList(), mock(InstanceContext.class))); + } + + @Test + void assertNewShardingRuleWithWrongShardingAlgorithmInDefaultTableShardingStrategy() { + ShardingRuleConfiguration ruleConfig = new ShardingRuleConfiguration(); + ruleConfig.setDefaultTableShardingStrategy(new StandardShardingStrategyConfiguration("order_id", "MOD")); + ruleConfig.getShardingAlgorithms().put("MOD", new AlgorithmConfiguration("MOD", PropertiesBuilder.build(new Property("sharding-count", "2")))); + assertThrows(ShardingAlgorithmInitializationException.class, () -> new ShardingRule(ruleConfig, Collections.emptyList(), mock(InstanceContext.class))); + } + + @Test + void assertNewShardingRuleWithWrongShardingAlgorithmInDatabaseShardingStrategy() { + ShardingRuleConfiguration ruleConfig = new ShardingRuleConfiguration(); + ShardingTableRuleConfiguration tableRuleConfig = new ShardingTableRuleConfiguration("t_order", ""); + tableRuleConfig.setDatabaseShardingStrategy(new StandardShardingStrategyConfiguration("order_id", "MOD")); + ruleConfig.getTables().add(tableRuleConfig); + ruleConfig.getShardingAlgorithms().put("MOD", new AlgorithmConfiguration("MOD", PropertiesBuilder.build(new Property("sharding-count", "2")))); + assertThrows(ShardingAlgorithmInitializationException.class, () -> new ShardingRule(ruleConfig, Collections.emptyList(), mock(InstanceContext.class))); + } + + @Test + void assertNewShardingRuleWithWrongShardingAlgorithmInTableShardingStrategy() { + ShardingRuleConfiguration ruleConfig = new ShardingRuleConfiguration(); + ShardingTableRuleConfiguration tableRuleConfig = new ShardingTableRuleConfiguration("t_order", ""); + tableRuleConfig.setTableShardingStrategy(new StandardShardingStrategyConfiguration("order_id", "MOD")); + ruleConfig.getTables().add(tableRuleConfig); + ruleConfig.getShardingAlgorithms().put("MOD", new AlgorithmConfiguration("MOD", PropertiesBuilder.build(new Property("sharding-count", "2")))); + assertThrows(ShardingAlgorithmInitializationException.class, () -> new ShardingRule(ruleConfig, Collections.emptyList(), mock(InstanceContext.class))); + } + + @Test + void assertNewShardingRuleWithWrongShardingAlgorithmInAutoTableShardingStrategy() { + ShardingRuleConfiguration ruleConfig = new ShardingRuleConfiguration(); + ShardingAutoTableRuleConfiguration autoTableRuleConfig = new ShardingAutoTableRuleConfiguration("t_order", "ds_0,ds_1"); + autoTableRuleConfig.setShardingStrategy(new StandardShardingStrategyConfiguration("order_id", "INLINE")); + ruleConfig.getAutoTables().add(autoTableRuleConfig); + ruleConfig.getShardingAlgorithms().put("INLINE", new AlgorithmConfiguration("INLINE", PropertiesBuilder.build(new Property("algorithm-expression", "t_order_%{order_id % 2}")))); + assertThrows(ShardingAlgorithmInitializationException.class, () -> new ShardingRule(ruleConfig, Collections.emptyList(), mock(InstanceContext.class))); + } + @Test void assertFindTableRule() { assertTrue(createMaximumShardingRule().findTableRule("logic_Table").isPresent());