Skip to content

Commit

Permalink
Merge pull request #1211 from tristaZero/dev
Browse files Browse the repository at this point in the history
 Sharding-JDBC spring namespace enhancement
  • Loading branch information
terrymanu committed Aug 31, 2018
2 parents c61bc67 + 1fe6104 commit c532fa0
Show file tree
Hide file tree
Showing 17 changed files with 299 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,34 @@
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;

/**
* 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<String> slaveDataSourceNames;
private Collection<String> slaveDataSourceNames;

private MasterSlaveLoadBalanceAlgorithm loadBalanceAlgorithm;

public MasterSlaveRuleConfiguration(final String name, final String masterDataSourceName, final Collection<String> slaveDataSourceNames) {
this.name = name;
this.masterDataSourceName = masterDataSourceName;
this.slaveDataSourceNames = slaveDataSourceNames;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -108,6 +113,45 @@ private void parseDefaultTableShardingStrategy(final BeanDefinitionBuilder facto
}
}

private List<BeanDefinition> parseMasterSlaveRulesConfig(final Element element) {
Element masterSlaveRulesElement = DomUtils.getChildElementByTagName(element, ShardingDataSourceBeanDefinitionParserTag.MASTER_SLAVE_RULES_TAG);
if (null == masterSlaveRulesElement) {
return new LinkedList<>();
}
List<Element> masterSlaveRuleElements = DomUtils.getChildElementsByTagName(masterSlaveRulesElement, ShardingDataSourceBeanDefinitionParserTag.MASTER_SLAVE_RULE_TAG);
List<BeanDefinition> 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<String> parseSlaveDataSourcesRef(final Element element) {
List<String> slaveDataSources = Splitter.on(",").trimResults().splitToList(element.getAttribute(MasterSlaveDataSourceBeanDefinitionParserTag.SLAVE_DATA_SOURCE_NAMES_ATTRIBUTE));
Collection<String> result = new ManagedList<>(slaveDataSources.size());
result.addAll(slaveDataSources);
return result;
}

private List<BeanDefinition> parseTableRulesConfig(final Element element) {
Element tableRulesElement = DomUtils.getChildElementByTagName(element, ShardingDataSourceBeanDefinitionParserTag.TABLE_RULES_TAG);
List<Element> tableRuleElements = DomUtils.getChildElementsByTagName(tableRulesElement, ShardingDataSourceBeanDefinitionParserTag.TABLE_RULE_TAG);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<xsd:element name="sharding-rule">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="master-slave-rules" minOccurs="0" />
<xsd:element ref="table-rules" />
<xsd:element ref="binding-table-rules" minOccurs="0" />
</xsd:sequence>
Expand Down Expand Up @@ -91,6 +92,23 @@
<xsd:attribute name="id" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>

<xsd:element name="master-slave-rules">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="master-slave-rule" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="master-slave-rule">
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="required" />
<xsd:attribute name="master-data-source-name" type="xsd:string" use="required" />
<xsd:attribute name="slave-data-source-names" type="xsd:string" use="required" />
<xsd:attribute name="strategy-ref" type="xsd:string" />
<xsd:attribute name="strategy-type" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="config-map">
<xsd:complexType>
<xsd:complexContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -67,38 +62,6 @@ public void assertRefMasterSlaveDataSource() {
assertTrue(masterSlaveRule.getLoadBalanceAlgorithm() == randomStrategy);
}

@Test
public void assertDefaultShardingDataSource() {
Map<String, DataSource> 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<String, DataSource> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -107,6 +109,34 @@ public void assertSimpleShardingDataSource() {
assertThat(shardingRule.getTableRules().iterator().next().getLogicTable(), is("t_order"));
}

@Test
public void assertmasterSlaveShardingDataSourceByDefaultStrategy() {
Map<String, DataSource> 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<String, DataSource> 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<String, DataSource> dataSourceMap = getDataSourceMap("shardingRuleWithAttributesDataSource");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,4 @@
<entry key="key1" value="value1" />
</master-slave:config-map>
</master-slave:data-source>

<sharding:data-source id="defaultShardingDataSource">
<sharding:sharding-rule data-source-names="randomMasterSlaveDataSource,refMasterSlaveDataSource" default-data-source-name="randomMasterSlaveDataSource">
<sharding:table-rules>
<sharding:table-rule logic-table="t_order" />
</sharding:table-rules>
</sharding:sharding-rule>
</sharding:data-source>
</beans>
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@
http://shardingsphere.io/schema/shardingsphere/sharding/sharding.xsd
">
<import resource="datasource/dataSource.xml" />

<import resource="datasource/masterSlaveDataSource.xml" />

<bean id="preciseModuloDatabaseShardingAlgorithm" class="io.shardingsphere.jdbc.spring.algorithm.PreciseModuloDatabaseShardingAlgorithm" />
<bean id="preciseModuloTableShardingAlgorithm" class="io.shardingsphere.jdbc.spring.algorithm.PreciseModuloTableShardingAlgorithm" />
<bean id="rangeModuloTableShardingAlgorithm" class="io.shardingsphere.jdbc.spring.algorithm.RangeModuloTableShardingAlgorithm" />
<bean id="defaultComplexKeysShardingAlgorithm" class="io.shardingsphere.jdbc.spring.algorithm.DefaultComplexKeysShardingAlgorithm" />
<bean id="defaultHintShardingAlgorithm" class="io.shardingsphere.jdbc.spring.algorithm.DefaultHintShardingAlgorithm" />
<bean id="keyGenerator" class="io.shardingsphere.jdbc.spring.fixture.IncrementKeyGenerator" />

<bean id="randomStrategy" class="io.shardingsphere.core.api.algorithm.masterslave.RandomMasterSlaveLoadBalanceAlgorithm" />

<sharding:standard-strategy id="standardStrategy" sharding-column="user_id" precise-algorithm-ref="preciseModuloDatabaseShardingAlgorithm" />
<sharding:standard-strategy id="rangeStandardStrategy" sharding-column="order_id" precise-algorithm-ref="preciseModuloTableShardingAlgorithm" range-algorithm-ref="rangeModuloTableShardingAlgorithm" />
<sharding:complex-strategy id="complexStrategy" sharding-columns="order_id,user_id" algorithm-ref="defaultComplexKeysShardingAlgorithm" />
Expand All @@ -30,6 +32,30 @@
</sharding:table-rules>
</sharding:sharding-rule>
</sharding:data-source>

<sharding:data-source id="masterSlaveShardingDataSourceByDefaultStrategy">
<sharding:sharding-rule data-source-names="dbtbl_0_master,dbtbl_0_slave_0,dbtbl_0_slave_1,dbtbl_1_master,dbtbl_1_slave_0,dbtbl_1_slave_1" default-key-generator-ref="keyGenerator">
<sharding:master-slave-rules>
<sharding:master-slave-rule id="dbtbl_0" master-data-source-name="dbtbl_0_master" slave-data-source-names="dbtbl_0_slave_0,dbtbl_0_slave_1"/>
<sharding:master-slave-rule id="dbtbl_1" master-data-source-name="dbtbl_1_master" slave-data-source-names="dbtbl_1_slave_0,dbtbl_1_slave_1"/>
</sharding:master-slave-rules>
<sharding:table-rules>
<sharding:table-rule logic-table="t_order" actual-data-nodes="dbtbl_${0..1}.t_order_${0..3}" database-strategy-ref="standardStrategy" table-strategy-ref="inlineStrategy" generate-key-column-name="order_id" key-generator-ref="keyGenerator" />
</sharding:table-rules>
</sharding:sharding-rule>
</sharding:data-source>

<sharding:data-source id="masterSlaveShardingDataSourceByUserStrategy">
<sharding:sharding-rule data-source-names="dbtbl_0_master,dbtbl_0_slave_0,dbtbl_0_slave_1,dbtbl_1_master,dbtbl_1_slave_0,dbtbl_1_slave_1" default-key-generator-ref="keyGenerator">
<sharding:master-slave-rules>
<sharding:master-slave-rule id="dbtbl_0" master-data-source-name="dbtbl_0_master" slave-data-source-names="dbtbl_0_slave_0,dbtbl_0_slave_1" strategy-ref="randomStrategy"/>
<sharding:master-slave-rule id="dbtbl_1" master-data-source-name="dbtbl_1_master" slave-data-source-names="dbtbl_1_slave_0,dbtbl_1_slave_1" strategy-ref="randomStrategy"/>
</sharding:master-slave-rules>
<sharding:table-rules>
<sharding:table-rule logic-table="t_order" actual-data-nodes="dbtbl_${0..1}.t_order_${0..3}" database-strategy-ref="standardStrategy" table-strategy-ref="inlineStrategy" generate-key-column-name="order_id" key-generator-ref="keyGenerator" />
</sharding:table-rules>
</sharding:sharding-rule>
</sharding:data-source>

<sharding:data-source id="shardingRuleWithAttributesDataSource">
<sharding:sharding-rule
Expand Down
Loading

0 comments on commit c532fa0

Please sign in to comment.