diff --git a/sharding-core/src/main/java/io/shardingsphere/core/api/config/MasterSlaveRuleConfiguration.java b/sharding-core/src/main/java/io/shardingsphere/core/api/config/MasterSlaveRuleConfiguration.java index 0480fbbd4a4c5..9d0896e8c5f44 100644 --- a/sharding-core/src/main/java/io/shardingsphere/core/api/config/MasterSlaveRuleConfiguration.java +++ b/sharding-core/src/main/java/io/shardingsphere/core/api/config/MasterSlaveRuleConfiguration.java @@ -20,7 +20,8 @@ import io.shardingsphere.core.api.algorithm.masterslave.MasterSlaveLoadBalanceAlgorithm; import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.RequiredArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Setter; import java.util.Collection; @@ -28,17 +29,25 @@ * Master-slave rule configuration. * * @author zhangliang + * @author panjuan */ +@NoArgsConstructor @AllArgsConstructor -@RequiredArgsConstructor @Getter +@Setter public final class MasterSlaveRuleConfiguration { - private final String name; + private String name; - private final String masterDataSourceName; + private String masterDataSourceName; - private final Collection slaveDataSourceNames; + private Collection slaveDataSourceNames; private MasterSlaveLoadBalanceAlgorithm loadBalanceAlgorithm; + + public MasterSlaveRuleConfiguration(final String name, final String masterDataSourceName, final Collection slaveDataSourceNames) { + this.name = name; + this.masterDataSourceName = masterDataSourceName; + this.slaveDataSourceNames = slaveDataSourceNames; + } } diff --git a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/main/java/io/shardingsphere/jdbc/spring/namespace/constants/ShardingDataSourceBeanDefinitionParserTag.java b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/main/java/io/shardingsphere/jdbc/spring/namespace/constants/ShardingDataSourceBeanDefinitionParserTag.java index 0437cf18d215b..3c79c58296a97 100644 --- a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/main/java/io/shardingsphere/jdbc/spring/namespace/constants/ShardingDataSourceBeanDefinitionParserTag.java +++ b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/main/java/io/shardingsphere/jdbc/spring/namespace/constants/ShardingDataSourceBeanDefinitionParserTag.java @@ -44,6 +44,10 @@ public final class ShardingDataSourceBeanDefinitionParserTag { public static final String TABLE_RULE_TAG = "table-rule"; + public static final String MASTER_SLAVE_RULES_TAG = "master-slave-rules"; + + public static final String MASTER_SLAVE_RULE_TAG = "master-slave-rule"; + public static final String BINDING_TABLE_RULES_TAG = "binding-table-rules"; public static final String BINDING_TABLE_RULE_TAG = "binding-table-rule"; diff --git a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/main/java/io/shardingsphere/jdbc/spring/namespace/parser/ShardingDataSourceBeanDefinitionParser.java b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/main/java/io/shardingsphere/jdbc/spring/namespace/parser/ShardingDataSourceBeanDefinitionParser.java index 82ed1202dd671..0d8394b1cfdb1 100644 --- a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/main/java/io/shardingsphere/jdbc/spring/namespace/parser/ShardingDataSourceBeanDefinitionParser.java +++ b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/main/java/io/shardingsphere/jdbc/spring/namespace/parser/ShardingDataSourceBeanDefinitionParser.java @@ -19,9 +19,12 @@ import com.google.common.base.Splitter; import com.google.common.base.Strings; +import io.shardingsphere.core.api.algorithm.masterslave.MasterSlaveLoadBalanceAlgorithmType; +import io.shardingsphere.core.api.config.MasterSlaveRuleConfiguration; import io.shardingsphere.core.api.config.ShardingRuleConfiguration; import io.shardingsphere.core.api.config.TableRuleConfiguration; import io.shardingsphere.jdbc.spring.datasource.SpringShardingDataSource; +import io.shardingsphere.jdbc.spring.namespace.constants.MasterSlaveDataSourceBeanDefinitionParserTag; import io.shardingsphere.jdbc.spring.namespace.constants.ShardingDataSourceBeanDefinitionParserTag; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.RuntimeBeanReference; @@ -34,6 +37,7 @@ import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; +import java.util.Collection; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -75,6 +79,7 @@ private BeanDefinition parseShardingRuleConfig(final Element element) { parseDefaultDatabaseShardingStrategy(factory, shardingRuleElement); parseDefaultTableShardingStrategy(factory, shardingRuleElement); factory.addPropertyValue("tableRuleConfigs", parseTableRulesConfig(shardingRuleElement)); + factory.addPropertyValue("masterSlaveRuleConfigs", parseMasterSlaveRulesConfig(shardingRuleElement)); factory.addPropertyValue("bindingTableGroups", parseBindingTablesConfig(shardingRuleElement)); parseKeyGenerator(factory, shardingRuleElement); return factory.getBeanDefinition(); @@ -108,6 +113,45 @@ private void parseDefaultTableShardingStrategy(final BeanDefinitionBuilder facto } } + private List parseMasterSlaveRulesConfig(final Element element) { + Element masterSlaveRulesElement = DomUtils.getChildElementByTagName(element, ShardingDataSourceBeanDefinitionParserTag.MASTER_SLAVE_RULES_TAG); + if (null == masterSlaveRulesElement) { + return new LinkedList<>(); + } + List masterSlaveRuleElements = DomUtils.getChildElementsByTagName(masterSlaveRulesElement, ShardingDataSourceBeanDefinitionParserTag.MASTER_SLAVE_RULE_TAG); + List result = new ManagedList<>(masterSlaveRuleElements.size()); + for (Element each : masterSlaveRuleElements) { + result.add(parseMasterSlaveRuleConfig(each)); + } + return result; + } + + private BeanDefinition parseMasterSlaveRuleConfig(final Element masterSlaveElement) { + BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(MasterSlaveRuleConfiguration.class); + factory.addPropertyValue("name", masterSlaveElement.getAttribute(ID_ATTRIBUTE)); + factory.addPropertyValue("masterDataSourceName", masterSlaveElement.getAttribute(MasterSlaveDataSourceBeanDefinitionParserTag.MASTER_DATA_SOURCE_NAME_ATTRIBUTE)); + factory.addPropertyValue("slaveDataSourceNames", parseSlaveDataSourcesRef(masterSlaveElement)); + String strategyRef = masterSlaveElement.getAttribute(MasterSlaveDataSourceBeanDefinitionParserTag.STRATEGY_REF_ATTRIBUTE); + if (!Strings.isNullOrEmpty(strategyRef)) { + factory.addPropertyReference("loadBalanceAlgorithm", strategyRef); + } else { + factory.addPropertyValue("loadBalanceAlgorithm", parseStrategyType(masterSlaveElement).getAlgorithm()); + } + return factory.getBeanDefinition(); + } + + private MasterSlaveLoadBalanceAlgorithmType parseStrategyType(final Element element) { + String result = element.getAttribute(MasterSlaveDataSourceBeanDefinitionParserTag.STRATEGY_TYPE_ATTRIBUTE); + return Strings.isNullOrEmpty(result) ? MasterSlaveLoadBalanceAlgorithmType.getDefaultAlgorithmType() : MasterSlaveLoadBalanceAlgorithmType.valueOf(result); + } + + private Collection parseSlaveDataSourcesRef(final Element element) { + List slaveDataSources = Splitter.on(",").trimResults().splitToList(element.getAttribute(MasterSlaveDataSourceBeanDefinitionParserTag.SLAVE_DATA_SOURCE_NAMES_ATTRIBUTE)); + Collection result = new ManagedList<>(slaveDataSources.size()); + result.addAll(slaveDataSources); + return result; + } + private List parseTableRulesConfig(final Element element) { Element tableRulesElement = DomUtils.getChildElementByTagName(element, ShardingDataSourceBeanDefinitionParserTag.TABLE_RULES_TAG); List tableRuleElements = DomUtils.getChildElementsByTagName(tableRulesElement, ShardingDataSourceBeanDefinitionParserTag.TABLE_RULE_TAG); diff --git a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/main/resources/META-INF/namespace/sharding.xsd b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/main/resources/META-INF/namespace/sharding.xsd index 60ba8a046a61c..d50cbed0bc44e 100644 --- a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/main/resources/META-INF/namespace/sharding.xsd +++ b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/main/resources/META-INF/namespace/sharding.xsd @@ -18,6 +18,7 @@ + @@ -91,6 +92,23 @@ + + + + + + + + + + + + + + + + + diff --git a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/java/io/shardingsphere/jdbc/spring/MasterSlaveNamespaceTest.java b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/java/io/shardingsphere/jdbc/spring/MasterSlaveNamespaceTest.java index 4c03dbd528fbe..1c4cae55a27fb 100644 --- a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/java/io/shardingsphere/jdbc/spring/MasterSlaveNamespaceTest.java +++ b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/java/io/shardingsphere/jdbc/spring/MasterSlaveNamespaceTest.java @@ -22,22 +22,17 @@ import io.shardingsphere.core.api.algorithm.masterslave.RandomMasterSlaveLoadBalanceAlgorithm; import io.shardingsphere.core.api.algorithm.masterslave.RoundRobinMasterSlaveLoadBalanceAlgorithm; import io.shardingsphere.core.jdbc.core.datasource.MasterSlaveDataSource; -import io.shardingsphere.core.jdbc.core.datasource.ShardingDataSource; import io.shardingsphere.core.rule.MasterSlaveRule; -import io.shardingsphere.core.rule.ShardingRule; -import io.shardingsphere.jdbc.spring.datasource.SpringMasterSlaveDataSource; import io.shardingsphere.jdbc.spring.util.FieldValueUtil; import org.junit.Test; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; -import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -67,38 +62,6 @@ public void assertRefMasterSlaveDataSource() { assertTrue(masterSlaveRule.getLoadBalanceAlgorithm() == randomStrategy); } - @Test - public void assertDefaultShardingDataSource() { - Map dataSourceMap = getDataSourceMap("defaultShardingDataSource"); - assertNotNull(dataSourceMap.get("dbtbl_0_master")); - assertNotNull(dataSourceMap.get("dbtbl_0_slave_0")); - assertNotNull(dataSourceMap.get("dbtbl_0_slave_1")); - assertNotNull(dataSourceMap.get("dbtbl_1_master")); - assertNotNull(dataSourceMap.get("dbtbl_1_slave_0")); - assertNotNull(dataSourceMap.get("dbtbl_1_slave_1")); - ShardingRule shardingRule = getShardingRule("defaultShardingDataSource"); - assertThat(shardingRule.getShardingDataSourceNames().getDefaultDataSourceName(), is("randomMasterSlaveDataSource")); - assertThat(shardingRule.getTableRules().size(), is(1)); - assertThat(shardingRule.getTableRules().iterator().next().getLogicTable(), is("t_order")); - } - - @Test - public void assertShardingDataSourceType() { - assertTrue(this.applicationContext.getBean("defaultMasterSlaveDataSource", MasterSlaveDataSource.class) instanceof SpringMasterSlaveDataSource); - } - - @SuppressWarnings("unchecked") - private Map getDataSourceMap(final String shardingDataSourceName) { - ShardingDataSource shardingDataSource = this.applicationContext.getBean(shardingDataSourceName, ShardingDataSource.class); - return shardingDataSource.getDataSourceMap(); - } - - private ShardingRule getShardingRule(final String shardingDataSourceName) { - ShardingDataSource shardingDataSource = this.applicationContext.getBean(shardingDataSourceName, ShardingDataSource.class); - Object shardingContext = FieldValueUtil.getFieldValue(shardingDataSource, "shardingContext", true); - return (ShardingRule) FieldValueUtil.getFieldValue(shardingContext, "shardingRule"); - } - private MasterSlaveRule getMasterSlaveRule(final String masterSlaveDataSourceName) { MasterSlaveDataSource masterSlaveDataSource = this.applicationContext.getBean(masterSlaveDataSourceName, MasterSlaveDataSource.class); return (MasterSlaveRule) FieldValueUtil.getFieldValue(masterSlaveDataSource, "masterSlaveRule", true); diff --git a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/java/io/shardingsphere/jdbc/spring/ShardingNamespaceTest.java b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/java/io/shardingsphere/jdbc/spring/ShardingNamespaceTest.java index 20d1d56a6c967..ceb12082de354 100644 --- a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/java/io/shardingsphere/jdbc/spring/ShardingNamespaceTest.java +++ b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/java/io/shardingsphere/jdbc/spring/ShardingNamespaceTest.java @@ -18,6 +18,8 @@ package io.shardingsphere.jdbc.spring; import io.shardingsphere.core.api.ConfigMapContext; +import io.shardingsphere.core.api.algorithm.masterslave.RandomMasterSlaveLoadBalanceAlgorithm; +import io.shardingsphere.core.api.algorithm.masterslave.RoundRobinMasterSlaveLoadBalanceAlgorithm; import io.shardingsphere.core.api.config.strategy.ComplexShardingStrategyConfiguration; import io.shardingsphere.core.api.config.strategy.HintShardingStrategyConfiguration; import io.shardingsphere.core.api.config.strategy.InlineShardingStrategyConfiguration; @@ -107,6 +109,34 @@ public void assertSimpleShardingDataSource() { assertThat(shardingRule.getTableRules().iterator().next().getLogicTable(), is("t_order")); } + @Test + public void assertmasterSlaveShardingDataSourceByDefaultStrategy() { + Map dataSourceMap = getDataSourceMap("masterSlaveShardingDataSourceByDefaultStrategy"); + assertNotNull(dataSourceMap.get("dbtbl_0_master")); + assertNotNull(dataSourceMap.get("dbtbl_0_slave_0")); + assertNotNull(dataSourceMap.get("dbtbl_1_master")); + assertNotNull(dataSourceMap.get("dbtbl_1_slave_1")); + ShardingRule shardingRule = getShardingRule("masterSlaveShardingDataSourceByDefaultStrategy"); + assertThat(shardingRule.getMasterSlaveRules().iterator().next().getLoadBalanceAlgorithm(), instanceOf(RoundRobinMasterSlaveLoadBalanceAlgorithm.class)); + assertThat(shardingRule.getTableRules().size(), is(1)); + assertThat(shardingRule.getTableRules().iterator().next().getLogicTable(), is("t_order")); + assertThat(shardingRule.getDefaultKeyGenerator(), instanceOf(IncrementKeyGenerator.class)); + } + + @Test + public void assertmasterSlaveShardingDataSourceByUserStrategy() { + Map dataSourceMap = getDataSourceMap("masterSlaveShardingDataSourceByUserStrategy"); + assertNotNull(dataSourceMap.get("dbtbl_0_master")); + assertNotNull(dataSourceMap.get("dbtbl_0_slave_0")); + assertNotNull(dataSourceMap.get("dbtbl_1_master")); + assertNotNull(dataSourceMap.get("dbtbl_1_slave_1")); + ShardingRule shardingRule = getShardingRule("masterSlaveShardingDataSourceByUserStrategy"); + assertThat(shardingRule.getMasterSlaveRules().iterator().next().getLoadBalanceAlgorithm(), instanceOf(RandomMasterSlaveLoadBalanceAlgorithm.class)); + assertThat(shardingRule.getTableRules().size(), is(1)); + assertThat(shardingRule.getTableRules().iterator().next().getLogicTable(), is("t_order")); + assertThat(shardingRule.getDefaultKeyGenerator(), instanceOf(IncrementKeyGenerator.class)); + } + @Test public void assertShardingRuleWithAttributesDataSource() { Map dataSourceMap = getDataSourceMap("shardingRuleWithAttributesDataSource"); diff --git a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/masterSlaveNamespace.xml b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/masterSlaveNamespace.xml index 65f15b2e5e251..01b9650011f46 100644 --- a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/masterSlaveNamespace.xml +++ b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/masterSlaveNamespace.xml @@ -27,12 +27,4 @@ - - - - - - - - diff --git a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/shardingNamespace.xml b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/shardingNamespace.xml index a9cb49279d2e1..0b3960d1062eb 100644 --- a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/shardingNamespace.xml +++ b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/shardingNamespace.xml @@ -8,14 +8,16 @@ http://shardingsphere.io/schema/shardingsphere/sharding/sharding.xsd "> - + + - + + @@ -30,6 +32,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + - + + + + + diff --git a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/withNamespaceForMasterSlaveWithStrategyRef.xml b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/withNamespaceForMasterSlaveWithStrategyRef.xml index d0443ae88ea91..619c036a2d666 100644 --- a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/withNamespaceForMasterSlaveWithStrategyRef.xml +++ b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/withNamespaceForMasterSlaveWithStrategyRef.xml @@ -2,27 +2,26 @@ - + + - - - - + - + + + + + diff --git a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/withNamespaceForMasterSlaveWithStrategyType.xml b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/withNamespaceForMasterSlaveWithStrategyType.xml index 532d05c7dc1f1..9df0eb4b69d70 100644 --- a/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/withNamespaceForMasterSlaveWithStrategyType.xml +++ b/sharding-jdbc-spring/sharding-jdbc-spring-namespace/src/test/resources/META-INF/rdb/withNamespaceForMasterSlaveWithStrategyType.xml @@ -2,25 +2,24 @@ - - - - + + - + + + + + diff --git a/sharding-jdbc/src/main/java/io/shardingsphere/core/jdbc/core/datasource/ShardingDataSource.java b/sharding-jdbc/src/main/java/io/shardingsphere/core/jdbc/core/datasource/ShardingDataSource.java index f1ce18fd7f101..1f2cccab5222c 100644 --- a/sharding-jdbc/src/main/java/io/shardingsphere/core/jdbc/core/datasource/ShardingDataSource.java +++ b/sharding-jdbc/src/main/java/io/shardingsphere/core/jdbc/core/datasource/ShardingDataSource.java @@ -18,23 +18,20 @@ package io.shardingsphere.core.jdbc.core.datasource; import io.shardingsphere.core.api.ConfigMapContext; -import io.shardingsphere.core.api.config.MasterSlaveRuleConfiguration; -import io.shardingsphere.core.api.config.ShardingRuleConfiguration; import io.shardingsphere.core.constant.ConnectionMode; import io.shardingsphere.core.constant.DatabaseType; import io.shardingsphere.core.constant.properties.ShardingProperties; import io.shardingsphere.core.constant.properties.ShardingPropertiesConstant; +import io.shardingsphere.core.exception.ShardingException; import io.shardingsphere.core.executor.ShardingExecuteEngine; import io.shardingsphere.core.jdbc.adapter.AbstractDataSourceAdapter; import io.shardingsphere.core.jdbc.core.ShardingContext; import io.shardingsphere.core.jdbc.core.connection.ShardingConnection; -import io.shardingsphere.core.rule.MasterSlaveRule; import io.shardingsphere.core.rule.ShardingRule; import lombok.Getter; import javax.sql.DataSource; import java.sql.SQLException; -import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; @@ -61,17 +58,26 @@ public ShardingDataSource(final Map dataSourceMap, final Sha public ShardingDataSource(final Map dataSourceMap, final ShardingRule shardingRule, final Map configMap, final Properties props) throws SQLException { super(dataSourceMap.values()); + checkDataSourceType(dataSourceMap); if (!configMap.isEmpty()) { ConfigMapContext.getInstance().getShardingConfig().putAll(configMap); } - this.dataSourceMap = getRawDataSourceMap(dataSourceMap); + this.dataSourceMap = dataSourceMap; this.shardingProperties = new ShardingProperties(null == props ? new Properties() : props); - this.shardingContext = getShardingContext(getRawDataSourceMap(dataSourceMap), getRevisedShardingRule(dataSourceMap, shardingRule)); + this.shardingContext = getShardingContext(dataSourceMap, shardingRule); + } + + private void checkDataSourceType(final Map dataSourceMap) { + for (DataSource each : dataSourceMap.values()) { + if (each instanceof MasterSlaveDataSource) { + throw new ShardingException("Initialized dataSources can not be master-slave DataSources."); + } + } } public ShardingDataSource(final Map dataSourceMap, final ShardingContext shardingContext, final ShardingProperties shardingProperties, final DatabaseType databaseType) { super(databaseType); - this.dataSourceMap = getRawDataSourceMap(dataSourceMap); + this.dataSourceMap = dataSourceMap; this.shardingContext = shardingContext; this.shardingProperties = shardingProperties; } @@ -85,39 +91,6 @@ private ShardingContext getShardingContext(final Map dataSou return new ShardingContext(dataSourceMap, shardingRule, getDatabaseType(), executeEngine, connectionMode, maxConnectionsSizePerQuery, showSQL); } - private Map getRawDataSourceMap(final Map dataSourceMap) { - Map result = new LinkedHashMap<>(); - if (null == dataSourceMap) { - return result; - } - for (Map.Entry entry : dataSourceMap.entrySet()) { - String dataSourceName = entry.getKey(); - DataSource dataSource = entry.getValue(); - if (dataSource instanceof MasterSlaveDataSource) { - result.putAll(((MasterSlaveDataSource) dataSource).getAllDataSources()); - } else { - result.put(dataSourceName, dataSource); - } - } - return result; - } - - private ShardingRule getRevisedShardingRule(final Map dataSourceMap, final ShardingRule shardingRule) { - if (null == dataSourceMap || !shardingRule.getMasterSlaveRules().isEmpty()) { - return shardingRule; - } - ShardingRuleConfiguration shardingRuleConfiguration = shardingRule.getShardingRuleConfig(); - for (DataSource each : dataSourceMap.values()) { - if (!(each instanceof MasterSlaveDataSource)) { - continue; - } - MasterSlaveRule masterSlaveRule = ((MasterSlaveDataSource) each).getMasterSlaveRule(); - shardingRuleConfiguration.getMasterSlaveRuleConfigs().add(new MasterSlaveRuleConfiguration( - masterSlaveRule.getName(), masterSlaveRule.getMasterDataSourceName(), masterSlaveRule.getSlaveDataSourceNames(), masterSlaveRule.getLoadBalanceAlgorithm())); - } - return new ShardingRule(shardingRuleConfiguration, dataSourceMap.keySet()); - } - @Override public final ShardingConnection getConnection() { return new ShardingConnection(this); diff --git a/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/main/java/io/shardingsphere/jdbc/orchestration/spring/namespace/constants/ShardingDataSourceBeanDefinitionParserTag.java b/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/main/java/io/shardingsphere/jdbc/orchestration/spring/namespace/constants/ShardingDataSourceBeanDefinitionParserTag.java index 740892fad9bbc..0077f9b2665bb 100644 --- a/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/main/java/io/shardingsphere/jdbc/orchestration/spring/namespace/constants/ShardingDataSourceBeanDefinitionParserTag.java +++ b/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/main/java/io/shardingsphere/jdbc/orchestration/spring/namespace/constants/ShardingDataSourceBeanDefinitionParserTag.java @@ -44,6 +44,10 @@ public final class ShardingDataSourceBeanDefinitionParserTag { public static final String TABLE_RULE_TAG = "table-rule"; + public static final String MASTER_SLAVE_RULES_TAG = "master-slave-rules"; + + public static final String MASTER_SLAVE_RULE_TAG = "master-slave-rule"; + public static final String BINDING_TABLE_RULES_TAG = "binding-table-rules"; public static final String BINDING_TABLE_RULE_TAG = "binding-table-rule"; diff --git a/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/main/java/io/shardingsphere/jdbc/orchestration/spring/namespace/parser/OrchestrationShardingDataSourceBeanDefinitionParser.java b/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/main/java/io/shardingsphere/jdbc/orchestration/spring/namespace/parser/OrchestrationShardingDataSourceBeanDefinitionParser.java index b4ec120da5fef..31c69cba02f4b 100644 --- a/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/main/java/io/shardingsphere/jdbc/orchestration/spring/namespace/parser/OrchestrationShardingDataSourceBeanDefinitionParser.java +++ b/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/main/java/io/shardingsphere/jdbc/orchestration/spring/namespace/parser/OrchestrationShardingDataSourceBeanDefinitionParser.java @@ -19,11 +19,14 @@ import com.google.common.base.Splitter; import com.google.common.base.Strings; +import io.shardingsphere.core.api.algorithm.masterslave.MasterSlaveLoadBalanceAlgorithmType; +import io.shardingsphere.core.api.config.MasterSlaveRuleConfiguration; import io.shardingsphere.core.api.config.ShardingRuleConfiguration; import io.shardingsphere.core.api.config.TableRuleConfiguration; import io.shardingsphere.jdbc.orchestration.config.OrchestrationType; import io.shardingsphere.jdbc.orchestration.spring.datasource.OrchestrationShardingDataSourceFactoryBean; import io.shardingsphere.jdbc.orchestration.spring.datasource.SpringShardingDataSource; +import io.shardingsphere.jdbc.orchestration.spring.namespace.constants.MasterSlaveDataSourceBeanDefinitionParserTag; import io.shardingsphere.jdbc.orchestration.spring.namespace.constants.ShardingDataSourceBeanDefinitionParserTag; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.RuntimeBeanReference; @@ -35,6 +38,7 @@ import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; +import java.util.Collection; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -97,11 +101,51 @@ private BeanDefinition parseShardingRuleConfig(final Element element) { parseDefaultDatabaseShardingStrategy(factory, element); parseDefaultTableShardingStrategy(factory, element); factory.addPropertyValue("tableRuleConfigs", parseTableRulesConfig(element)); + factory.addPropertyValue("masterSlaveRuleConfigs", parseMasterSlaveRulesConfig(element)); factory.addPropertyValue("bindingTableGroups", parseBindingTablesConfig(element)); parseKeyGenerator(factory, element); return factory.getBeanDefinition(); } + private List parseMasterSlaveRulesConfig(final Element element) { + Element masterSlaveRulesElement = DomUtils.getChildElementByTagName(element, ShardingDataSourceBeanDefinitionParserTag.MASTER_SLAVE_RULES_TAG); + if (null == masterSlaveRulesElement) { + return new LinkedList<>(); + } + List masterSlaveRuleElements = DomUtils.getChildElementsByTagName(masterSlaveRulesElement, ShardingDataSourceBeanDefinitionParserTag.MASTER_SLAVE_RULE_TAG); + List result = new ManagedList<>(masterSlaveRuleElements.size()); + for (Element each : masterSlaveRuleElements) { + result.add(parseMasterSlaveRuleConfig(each)); + } + return result; + } + + private BeanDefinition parseMasterSlaveRuleConfig(final Element masterSlaveElement) { + BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(MasterSlaveRuleConfiguration.class); + factory.addPropertyValue("name", masterSlaveElement.getAttribute(ID_ATTRIBUTE)); + factory.addPropertyValue("masterDataSourceName", masterSlaveElement.getAttribute(MasterSlaveDataSourceBeanDefinitionParserTag.MASTER_DATA_SOURCE_NAME_ATTRIBUTE)); + factory.addPropertyValue("slaveDataSourceNames", parseSlaveDataSourcesRef(masterSlaveElement)); + String strategyRef = masterSlaveElement.getAttribute(MasterSlaveDataSourceBeanDefinitionParserTag.STRATEGY_REF_ATTRIBUTE); + if (!Strings.isNullOrEmpty(strategyRef)) { + factory.addPropertyReference("loadBalanceAlgorithm", strategyRef); + } else { + factory.addPropertyValue("loadBalanceAlgorithm", parseStrategyType(masterSlaveElement).getAlgorithm()); + } + return factory.getBeanDefinition(); + } + + private MasterSlaveLoadBalanceAlgorithmType parseStrategyType(final Element element) { + String result = element.getAttribute(MasterSlaveDataSourceBeanDefinitionParserTag.STRATEGY_TYPE_ATTRIBUTE); + return Strings.isNullOrEmpty(result) ? MasterSlaveLoadBalanceAlgorithmType.getDefaultAlgorithmType() : MasterSlaveLoadBalanceAlgorithmType.valueOf(result); + } + + private Collection parseSlaveDataSourcesRef(final Element element) { + List slaveDataSources = Splitter.on(",").trimResults().splitToList(element.getAttribute(MasterSlaveDataSourceBeanDefinitionParserTag.SLAVE_DATA_SOURCE_NAMES_ATTRIBUTE)); + Collection result = new ManagedList<>(slaveDataSources.size()); + result.addAll(slaveDataSources); + return result; + } + private void parseKeyGenerator(final BeanDefinitionBuilder factory, final Element element) { String keyGenerator = element.getAttribute(ShardingDataSourceBeanDefinitionParserTag.DEFAULT_KEY_GENERATOR_REF_ATTRIBUTE); if (!Strings.isNullOrEmpty(keyGenerator)) { diff --git a/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/main/resources/META-INF/namespace/orchestration-sharding.xsd b/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/main/resources/META-INF/namespace/orchestration-sharding.xsd index b4f2a6a1235d7..3251e1b68c851 100644 --- a/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/main/resources/META-INF/namespace/orchestration-sharding.xsd +++ b/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/main/resources/META-INF/namespace/orchestration-sharding.xsd @@ -20,6 +20,7 @@ + @@ -93,6 +94,22 @@ + + + + + + + + + + + + + + + + diff --git a/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/test/java/io/shardingsphere/jdbc/orchestration/spring/OrchestrationShardingMasterSlaveNamespaceTest.java b/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/test/java/io/shardingsphere/jdbc/orchestration/spring/OrchestrationShardingMasterSlaveNamespaceTest.java index dde0c99af462e..66befef25cc92 100644 --- a/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/test/java/io/shardingsphere/jdbc/orchestration/spring/OrchestrationShardingMasterSlaveNamespaceTest.java +++ b/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/test/java/io/shardingsphere/jdbc/orchestration/spring/OrchestrationShardingMasterSlaveNamespaceTest.java @@ -17,9 +17,11 @@ package io.shardingsphere.jdbc.orchestration.spring; +import io.shardingsphere.core.api.algorithm.masterslave.RoundRobinMasterSlaveLoadBalanceAlgorithm; import io.shardingsphere.core.jdbc.core.datasource.ShardingDataSource; import io.shardingsphere.core.rule.ShardingRule; import io.shardingsphere.jdbc.orchestration.internal.datasource.OrchestrationShardingDataSource; +import io.shardingsphere.jdbc.orchestration.spring.fixture.IncrementKeyGenerator; import io.shardingsphere.jdbc.orchestration.spring.util.EmbedTestingServer; import io.shardingsphere.jdbc.orchestration.spring.util.FieldValueUtil; import org.junit.BeforeClass; @@ -30,6 +32,7 @@ import javax.sql.DataSource; import java.util.Map; +import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; @@ -43,29 +46,42 @@ public static void init() { } @Test - public void assertDefaultShardingDataSource() { - Map dataSourceMap = getDataSourceMap(); + public void assertMasterSlaveShardingDataSourceByUserStrategy() { + Map dataSourceMap = getDataSourceMap("masterSlaveShardingDataSourceByUserStrategy"); assertNotNull(dataSourceMap.get("dbtbl_0_master")); assertNotNull(dataSourceMap.get("dbtbl_0_slave_0")); assertNotNull(dataSourceMap.get("dbtbl_0_slave_1")); assertNotNull(dataSourceMap.get("dbtbl_1_master")); assertNotNull(dataSourceMap.get("dbtbl_1_slave_0")); assertNotNull(dataSourceMap.get("dbtbl_1_slave_1")); - ShardingRule shardingRule = getShardingRule(); - assertThat(shardingRule.getShardingDataSourceNames().getDefaultDataSourceName(), is("defaultMasterSlaveDataSource")); + ShardingRule shardingRule = getShardingRule("masterSlaveShardingDataSourceByUserStrategy"); assertThat(shardingRule.getTableRules().size(), is(1)); assertThat(shardingRule.getTableRules().iterator().next().getLogicTable(), is("t_order")); } + @Test + public void assertMasterSlaveShardingDataSourceByDefaultStrategy() { + Map dataSourceMap = getDataSourceMap("masterSlaveShardingDataSourceByDefaultStrategy"); + assertNotNull(dataSourceMap.get("dbtbl_0_master")); + assertNotNull(dataSourceMap.get("dbtbl_0_slave_0")); + assertNotNull(dataSourceMap.get("dbtbl_1_master")); + assertNotNull(dataSourceMap.get("dbtbl_1_slave_1")); + ShardingRule shardingRule = getShardingRule("masterSlaveShardingDataSourceByDefaultStrategy"); + assertThat(shardingRule.getMasterSlaveRules().iterator().next().getLoadBalanceAlgorithm(), instanceOf(RoundRobinMasterSlaveLoadBalanceAlgorithm.class)); + assertThat(shardingRule.getTableRules().size(), is(1)); + assertThat(shardingRule.getTableRules().iterator().next().getLogicTable(), is("t_order")); + assertThat(shardingRule.getDefaultKeyGenerator(), instanceOf(IncrementKeyGenerator.class)); + } + @SuppressWarnings("unchecked") - private Map getDataSourceMap() { - OrchestrationShardingDataSource shardingDataSource = applicationContext.getBean("defaultShardingDataSource", OrchestrationShardingDataSource.class); + private Map getDataSourceMap(final String shardingDataSourceName) { + OrchestrationShardingDataSource shardingDataSource = applicationContext.getBean(shardingDataSourceName, OrchestrationShardingDataSource.class); ShardingDataSource dataSource = (ShardingDataSource) FieldValueUtil.getFieldValue(shardingDataSource, "dataSource"); return dataSource.getDataSourceMap(); } - private ShardingRule getShardingRule() { - OrchestrationShardingDataSource shardingDataSource = applicationContext.getBean("defaultShardingDataSource", OrchestrationShardingDataSource.class); + private ShardingRule getShardingRule(final String shardingDataSourceName) { + OrchestrationShardingDataSource shardingDataSource = applicationContext.getBean(shardingDataSourceName, OrchestrationShardingDataSource.class); ShardingDataSource dataSource = (ShardingDataSource) FieldValueUtil.getFieldValue(shardingDataSource, "dataSource"); Object shardingContext = FieldValueUtil.getFieldValue(dataSource, "shardingContext"); return (ShardingRule) FieldValueUtil.getFieldValue(shardingContext, "shardingRule"); diff --git a/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/test/resources/META-INF/rdb/shardingMasterSlaveNamespace.xml b/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/test/resources/META-INF/rdb/shardingMasterSlaveNamespace.xml index e16ad269880bb..0601508c1be04 100644 --- a/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/test/resources/META-INF/rdb/shardingMasterSlaveNamespace.xml +++ b/sharding-orchestration/sharding-jdbc-orchestration-spring/sharding-jdbc-orchestration-spring-namespace/src/test/resources/META-INF/rdb/shardingMasterSlaveNamespace.xml @@ -1,28 +1,50 @@ - + + + - - - - - - - + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + +