/* * Copyright 1999-2015 dangdang.com. * <p> * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * </p> */ package com.dangdang.ddframe.rdb.sharding.config.common.api; import com.dangdang.ddframe.rdb.sharding.api.rule.BindingTableRule; import com.dangdang.ddframe.rdb.sharding.api.rule.DataNode; import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule; import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule; import com.dangdang.ddframe.rdb.sharding.config.common.api.config.AutoIncrementColumnConfig; import com.dangdang.ddframe.rdb.sharding.config.common.api.config.BindingTableRuleConfig; import com.dangdang.ddframe.rdb.sharding.config.common.api.config.ShardingRuleConfig; import com.dangdang.ddframe.rdb.sharding.config.common.api.config.StrategyConfig; import com.dangdang.ddframe.rdb.sharding.config.common.api.config.TableRuleConfig; import com.dangdang.ddframe.rdb.sharding.config.common.fixture.DecrementIdGenerator; import com.dangdang.ddframe.rdb.sharding.config.common.internal.fixture.MultiAlgorithm; import com.dangdang.ddframe.rdb.sharding.config.common.internal.fixture.SingleAlgorithm; import com.google.common.base.Joiner; import org.junit.Test; import javax.sql.DataSource; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Map; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsCollectionContaining.hasItem; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; public final class ShardingRuleBuilderTest { @Test(expected = IllegalArgumentException.class) public void assertBuildFailureWhenDataSourceIsEmpty() { new ShardingRuleBuilder(new ShardingRuleConfig()).build(); } @Test(expected = IllegalArgumentException.class) public void assertBuildFailureWhenBindingTableError() { ShardingRuleConfig shardingRuleConfig = new ShardingRuleConfig(); shardingRuleConfig.setDataSource(createDataSourceMap()); shardingRuleConfig.setTables(createTableRuleConfigMap()); shardingRuleConfig.setBindingTables(Collections.singletonList(createBindingTableRule("t_other"))); shardingRuleConfig.setDefaultDatabaseStrategy(getDatabaseStrategyConfig(SingleAlgorithm.class.getName())); shardingRuleConfig.setDefaultTableStrategy(getTableStrategyConfigForExpression()); new ShardingRuleBuilder(shardingRuleConfig).build().getBindingTableRules().iterator().next().getTableRules().iterator().next(); } @Test(expected = IllegalArgumentException.class) public void assertBuildFailureWhenAlgorithmNotExisted() { ShardingRuleConfig shardingRuleConfig = new ShardingRuleConfig(); shardingRuleConfig.setDataSource(createDataSourceMap()); shardingRuleConfig.setTables(createTableRuleConfigMap()); shardingRuleConfig.setDefaultDatabaseStrategy(getDatabaseStrategyConfig("xxx.Algorithm")); new ShardingRuleBuilder(shardingRuleConfig).build(); } @Test(expected = IllegalArgumentException.class) public void assertBuildFailureWhenAutoIncrementClassNotExisted() { ShardingRuleConfig shardingRuleConfig = new ShardingRuleConfig(); shardingRuleConfig.setDataSource(createDataSourceMap()); shardingRuleConfig.setDefaultDataSourceName("ds_0"); shardingRuleConfig.setTables(createTableRuleConfigMap()); shardingRuleConfig.setIdGeneratorClass("not.existed"); shardingRuleConfig.setBindingTables(Collections.singletonList(createBindingTableRule("t_order", "t_order_item"))); shardingRuleConfig.setDefaultDatabaseStrategy(getDatabaseStrategyConfig(SingleAlgorithm.class.getName())); shardingRuleConfig.setDefaultTableStrategy(getTableStrategyConfigForAlgorithmClass()); new ShardingRuleBuilder(shardingRuleConfig).build(); } @Test public void assertBuildSuccess() { ShardingRuleConfig shardingRuleConfig = new ShardingRuleConfig(); shardingRuleConfig.setDataSource(createDataSourceMap()); shardingRuleConfig.setDefaultDataSourceName("ds_0"); shardingRuleConfig.setTables(createTableRuleConfigMap()); shardingRuleConfig.setIdGeneratorClass("com.dangdang.ddframe.rdb.sharding.config.common.fixture.IncrementIdGenerator"); shardingRuleConfig.setBindingTables(Collections.singletonList(createBindingTableRule("t_order", "t_order_item"))); shardingRuleConfig.setDefaultDatabaseStrategy(getDatabaseStrategyConfig(SingleAlgorithm.class.getName())); shardingRuleConfig.setDefaultTableStrategy(getTableStrategyConfigForAlgorithmClass()); ShardingRule actual = new ShardingRuleBuilder(shardingRuleConfig).build(); assertThat(actual.getDataSourceRule().getDataSourceNames().size(), is(2)); assertThat(actual.getDataSourceRule().getDataSourceNames(), hasItem("ds_0")); assertThat(actual.getDataSourceRule().getDataSourceNames(), hasItem("ds_1")); assertThat(actual.getTableRules().size(), is(3)); for (TableRule each : actual.getTableRules()) { String logicTable = each.getLogicTable(); switch (logicTable) { case "t_order": assertFalse(each.isDynamic()); assertThat(each.getActualTables().size(), is(4)); assertThat(each.getActualTables(), hasItem(new DataNode("ds_0", "t_order_0"))); assertThat(each.getActualTables(), hasItem(new DataNode("ds_0", "t_order_0"))); assertThat(each.getActualTables(), hasItem(new DataNode("ds_1", "t_order_0"))); assertThat(each.getActualTables(), hasItem(new DataNode("ds_1", "t_order_1"))); break; case "t_order_item": assertFalse(each.isDynamic()); assertThat(each.getActualTables().size(), is(4)); assertThat(each.getActualTables(), hasItem(new DataNode("ds_0", "t_order_item_0"))); assertThat(each.getActualTables(), hasItem(new DataNode("ds_0", "t_order_item_0"))); assertThat(each.getActualTables(), hasItem(new DataNode("ds_1", "t_order_item_0"))); assertThat(each.getActualTables(), hasItem(new DataNode("ds_1", "t_order_item_1"))); break; case "t_log": assertTrue(each.isDynamic()); assertThat(each.getActualTables().size(), is(2)); assertThat(each.getActualTables(), hasItem(new DataNode("ds_0", "SHARDING_JDBC DYNAMIC_TABLE_PLACEHOLDER"))); assertThat(each.getActualTables(), hasItem(new DataNode("ds_1", "SHARDING_JDBC DYNAMIC_TABLE_PLACEHOLDER"))); break; default: fail(); } } assertThat(actual.getBindingTableRules().size(), is(1)); BindingTableRule bindingTableRule = actual.getBindingTableRules().iterator().next(); assertTrue(bindingTableRule.hasLogicTable("t_order")); assertTrue(bindingTableRule.hasLogicTable("t_order_item")); assertFalse(bindingTableRule.hasLogicTable("t_log")); assertThat(actual.getDatabaseShardingStrategy().getShardingColumns().size(), is(1)); assertThat(actual.getDatabaseShardingStrategy().getShardingColumns().iterator().next(), is("uid")); assertThat(actual.getTableShardingStrategy().getShardingColumns().size(), is(1)); assertThat(actual.getTableShardingStrategy().getShardingColumns().iterator().next(), is("oid")); } private Map<String, DataSource> createDataSourceMap() { Map<String, DataSource> result = new HashMap<>(2); result.put("ds_0", null); result.put("ds_1", null); return result; } private Map<String, TableRuleConfig> createTableRuleConfigMap() { Map<String, TableRuleConfig> result = new HashMap<>(3); result.put("t_order", createTableRuleConfig("t_order")); result.put("t_order_item", createTableRuleConfig("t_order_item")); result.put("t_log", createDynamicTableRuleConfig()); return result; } private TableRuleConfig createTableRuleConfig(final String logicTable) { TableRuleConfig result = new TableRuleConfig(); result.setActualTables(logicTable + "_${[0, 1]}"); result.setDataSourceNames("ds_${0..1}"); result.setDatabaseStrategy(getDatabaseStrategyConfig(SingleAlgorithm.class.getName())); result.setTableStrategy(getTableStrategyConfigForExpression()); Map<String, String> autoIncrementColumnMap = new HashMap<>(); autoIncrementColumnMap.put("order_id", null); AutoIncrementColumnConfig orderIdConfig = new AutoIncrementColumnConfig(); orderIdConfig.setColumnName("order_id"); autoIncrementColumnMap.put("order_item_id", "com.dangdang.ddframe.rdb.sharding.config.common.fixture.DecrementIdGenerator"); AutoIncrementColumnConfig orderItemIdConfig = new AutoIncrementColumnConfig(); orderItemIdConfig.setColumnName("order_item_id"); orderItemIdConfig.setColumnIdGeneratorClass(DecrementIdGenerator.class.getName()); result.setAutoIncrementColumns(Arrays.asList(orderIdConfig, orderItemIdConfig)); return result; } private StrategyConfig getDatabaseStrategyConfig(final String algorithmClassName) { StrategyConfig result = new StrategyConfig(); result.setShardingColumns("uid"); result.setAlgorithmClassName(algorithmClassName); return result; } private StrategyConfig getTableStrategyConfigForExpression() { StrategyConfig result = new StrategyConfig(); result.setShardingColumns("oid"); result.setAlgorithmExpression("${oid.longValue() % 2}"); return result; } private StrategyConfig getTableStrategyConfigForAlgorithmClass() { StrategyConfig result = new StrategyConfig(); result.setShardingColumns("oid"); result.setAlgorithmClassName(MultiAlgorithm.class.getName()); return result; } private TableRuleConfig createDynamicTableRuleConfig() { TableRuleConfig result = new TableRuleConfig(); result.setDynamic(true); return result; } private BindingTableRuleConfig createBindingTableRule(final String... logicTables) { BindingTableRuleConfig result = new BindingTableRuleConfig(); result.setTableNames(Joiner.on(",").join(logicTables)); return result; } }