You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2022/08/07 14:38:48 UTC

[shardingsphere] branch master updated: support Cartesian Product for readWriteConfig, add check database for writedatasoucename (#19808)

This is an automated email from the ASF dual-hosted git repository.

zhangliang 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 aa254d008fc support Cartesian Product for readWriteConfig, add check database for writedatasoucename (#19808)
aa254d008fc is described below

commit aa254d008fcebce9566e619d65a6b803d4c160cc
Author: natehuang <na...@tencent.com>
AuthorDate: Sun Aug 7 22:38:41 2022 +0800

    support Cartesian Product for readWriteConfig, add check database for writedatasoucename (#19808)
    
    * support Cartesian Product for readWriteConfig, add check database for write datasource
    
    * code check
    
    * code check 2
    
    Co-authored-by: Liang Zhang <zh...@apache.org>
---
 ...ReadwriteSplittingRuleConfigurationChecker.java | 14 +++--
 .../rule/ReadwriteSplittingRule.java               | 61 +++++++++++++++++++---
 ...writeSplittingRuleConfigurationCheckerTest.java |  4 +-
 .../spring/boot/SpringBootStarterTest.java         | 15 +++---
 .../boot/jndi/SpringBootJNDIDataSourceTest.java    |  8 +--
 .../src/test/resources/application-jndi.properties |  7 +--
 .../src/test/resources/application.properties      | 13 ++---
 7 files changed, 91 insertions(+), 31 deletions(-)

diff --git a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/AbstractReadwriteSplittingRuleConfigurationChecker.java b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/AbstractReadwriteSplittingRuleConfigurationChecker.java
index 1abed582975..157696a1835 100644
--- a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/AbstractReadwriteSplittingRuleConfigurationChecker.java
+++ b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/AbstractReadwriteSplittingRuleConfigurationChecker.java
@@ -23,6 +23,7 @@ import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
 import org.apache.shardingsphere.infra.config.rule.checker.RuleConfigurationChecker;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 import org.apache.shardingsphere.infra.rule.identifier.type.DynamicDataSourceContainedRule;
+import org.apache.shardingsphere.infra.util.expr.InlineExpressionParser;
 import org.apache.shardingsphere.readwritesplitting.algorithm.loadbalance.TransactionWeightReadQueryLoadBalanceAlgorithm;
 import org.apache.shardingsphere.readwritesplitting.algorithm.loadbalance.WeightReadQueryLoadBalanceAlgorithm;
 import org.apache.shardingsphere.readwritesplitting.api.rule.ReadwriteSplittingDataSourceRuleConfiguration;
@@ -70,11 +71,14 @@ public abstract class AbstractReadwriteSplittingRuleConfigurationChecker<T exten
                                      final Collection<String> readDataSourceNames, final StaticReadwriteSplittingStrategyConfiguration strategyConfig) {
         Preconditions.checkArgument(!Strings.isNullOrEmpty(strategyConfig.getWriteDataSourceName()), "Write data source name is required.");
         Preconditions.checkArgument(!strategyConfig.getReadDataSourceNames().isEmpty(), "Read data source names are required.");
-        strategyConfig.getReadDataSourceNames().forEach(each -> Preconditions.checkState(null != dataSourceMap.get(each), "Read data source name `%s` not in database `%s`.", each, databaseName));
-        Preconditions.checkState(writeDataSourceNames.add(strategyConfig.getWriteDataSourceName()),
-                "Can not config duplicate write dataSource `%s` in database `%s`.", strategyConfig.getWriteDataSourceName(), databaseName);
-        Preconditions.checkState(readDataSourceNames.addAll(strategyConfig.getReadDataSourceNames()),
-                "Can not config duplicate read dataSources `%s` in database `%s`.", strategyConfig.getReadDataSourceNames(), databaseName);
+        Collection<String> inlineWriteNames = new InlineExpressionParser(strategyConfig.getWriteDataSourceName()).splitAndEvaluate();
+        inlineWriteNames.forEach(each -> Preconditions.checkState(null != dataSourceMap.get(each), "Write data source name `%s` not in database `%s`.", each, databaseName));
+        inlineWriteNames.forEach(each -> Preconditions.checkState(writeDataSourceNames.add(each), "Can not config duplicate write dataSource `%s` in database `%s`.", each, databaseName));
+        for (String readName : readDataSourceNames) {
+            Collection<String> inlineReadNames = new InlineExpressionParser(readName).splitAndEvaluate();
+            inlineReadNames.forEach(each -> Preconditions.checkState(null != dataSourceMap.get(each), "Read data source name `%s` not in database `%s`.", each, databaseName));
+            inlineReadNames.forEach(each -> Preconditions.checkState(readDataSourceNames.add(each), "Can not config duplicate write dataSource `%s` in database `%s`.", each, databaseName));
+        }
     }
     
     private void checkDynamicStrategy(final Collection<ShardingSphereRule> rules, final DynamicReadwriteSplittingStrategyConfiguration dynamicStrategy) {
diff --git a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/rule/ReadwriteSplittingRule.java b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/rule/ReadwriteSplittingRule.java
index c0aaa95c2c3..0ff565ab8d8 100644
--- a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/rule/ReadwriteSplittingRule.java
+++ b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/main/java/org/apache/shardingsphere/readwritesplitting/rule/ReadwriteSplittingRule.java
@@ -30,11 +30,14 @@ import org.apache.shardingsphere.infra.rule.identifier.type.DataSourceContainedR
 import org.apache.shardingsphere.infra.rule.identifier.type.StaticDataSourceContainedRule;
 import org.apache.shardingsphere.infra.rule.identifier.type.StorageConnectorReusableRule;
 import org.apache.shardingsphere.infra.rule.identifier.type.exportable.ExportableRule;
+import org.apache.shardingsphere.infra.util.expr.InlineExpressionParser;
 import org.apache.shardingsphere.mode.metadata.storage.StorageNodeStatus;
 import org.apache.shardingsphere.mode.metadata.storage.event.StorageNodeDataSourceChangedEvent;
 import org.apache.shardingsphere.readwritesplitting.algorithm.config.AlgorithmProvidedReadwriteSplittingRuleConfiguration;
 import org.apache.shardingsphere.readwritesplitting.api.ReadwriteSplittingRuleConfiguration;
 import org.apache.shardingsphere.readwritesplitting.api.rule.ReadwriteSplittingDataSourceRuleConfiguration;
+import org.apache.shardingsphere.readwritesplitting.api.strategy.DynamicReadwriteSplittingStrategyConfiguration;
+import org.apache.shardingsphere.readwritesplitting.api.strategy.StaticReadwriteSplittingStrategyConfiguration;
 import org.apache.shardingsphere.readwritesplitting.factory.ReadQueryLoadBalanceAlgorithmFactory;
 import org.apache.shardingsphere.readwritesplitting.spi.ReadQueryLoadBalanceAlgorithm;
 import org.apache.shardingsphere.readwritesplitting.strategy.type.DynamicReadwriteSplittingStrategy;
@@ -43,9 +46,11 @@ import org.apache.shardingsphere.readwritesplitting.strategy.type.StaticReadwrit
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 /**
  * Readwrite-splitting rule.
@@ -64,9 +69,7 @@ public final class ReadwriteSplittingRule implements DatabaseRule, DataSourceCon
         ruleConfig.getLoadBalancers().forEach((key, value) -> loadBalancers.put(key, ReadQueryLoadBalanceAlgorithmFactory.newInstance(value)));
         dataSourceRules = new HashMap<>(ruleConfig.getDataSources().size(), 1);
         for (ReadwriteSplittingDataSourceRuleConfiguration each : ruleConfig.getDataSources()) {
-            ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm = null == loadBalancers.get(each.getLoadBalancerName()) ? ReadQueryLoadBalanceAlgorithmFactory.newInstance()
-                    : loadBalancers.get(each.getLoadBalancerName());
-            dataSourceRules.put(each.getName(), new ReadwriteSplittingDataSourceRule(each, loadBalanceAlgorithm, builtRules));
+            dataSourceRules.putAll(buildReadwriteSplittingDataSourceRules(each, builtRules));
         }
     }
     
@@ -75,12 +78,58 @@ public final class ReadwriteSplittingRule implements DatabaseRule, DataSourceCon
         loadBalancers.putAll(ruleConfig.getLoadBalanceAlgorithms());
         dataSourceRules = new HashMap<>(ruleConfig.getDataSources().size(), 1);
         for (ReadwriteSplittingDataSourceRuleConfiguration each : ruleConfig.getDataSources()) {
-            ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm = null == loadBalancers.get(each.getLoadBalancerName()) ? ReadQueryLoadBalanceAlgorithmFactory.newInstance()
-                    : loadBalancers.get(each.getLoadBalancerName());
-            dataSourceRules.put(each.getName(), new ReadwriteSplittingDataSourceRule(each, loadBalanceAlgorithm, builtRules));
+            dataSourceRules.putAll(buildReadwriteSplittingDataSourceRules(each, builtRules));
         }
     }
     
+    private Map<String, ReadwriteSplittingDataSourceRule> buildReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config,
+                                                                                                 final Collection<ShardingSphereRule> builtRules) {
+        ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm = null == loadBalancers.get(config.getLoadBalancerName())
+                ? ReadQueryLoadBalanceAlgorithmFactory.newInstance()
+                : loadBalancers.get(config.getLoadBalancerName());
+        if (null != config.getStaticStrategy()) {
+            return buildStaticReadwriteSplittingDataSourceRules(config, builtRules, loadBalanceAlgorithm);
+        } else {
+            return buildDynamicReadwriteSplittingDataSourceRules(config, builtRules, loadBalanceAlgorithm);
+        }
+    }
+
+    private Map<String, ReadwriteSplittingDataSourceRule> buildStaticReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config,
+                                                                                                       final Collection<ShardingSphereRule> builtRules,
+                                                                                                       final ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm) {
+        Map<String, ReadwriteSplittingDataSourceRule> result = new LinkedHashMap<>();
+        List<String> readwriteInlineNames = new InlineExpressionParser(config.getName()).splitAndEvaluate();
+        List<String> writeInlineDatasourceNames = new InlineExpressionParser(config.getStaticStrategy().getWriteDataSourceName()).splitAndEvaluate();
+        List<List<String>> readInlineDatasourceNames = config.getStaticStrategy().getReadDataSourceNames().stream()
+                .map(each -> new InlineExpressionParser(each).splitAndEvaluate()).collect(Collectors.toList());
+        Preconditions.checkArgument(writeInlineDatasourceNames.size() == readwriteInlineNames.size(), "Inline expression write data source names size error");
+        readInlineDatasourceNames.forEach(e -> Preconditions.checkArgument(e.size() == readwriteInlineNames.size(), "Inline expression read data source names size error"));
+        for (int i = 0; i < readwriteInlineNames.size(); i++) {
+            final int index = i;
+            ReadwriteSplittingDataSourceRuleConfiguration staticConfig = new ReadwriteSplittingDataSourceRuleConfiguration(readwriteInlineNames.get(index),
+                    new StaticReadwriteSplittingStrategyConfiguration(writeInlineDatasourceNames.get(index),
+                            readInlineDatasourceNames.stream().map(each -> each.get(index)).collect(Collectors.toList())),
+                    null, config.getLoadBalancerName());
+            result.put(readwriteInlineNames.get(i), new ReadwriteSplittingDataSourceRule(staticConfig, loadBalanceAlgorithm, builtRules));
+        }
+        return result;
+    }
+
+    private Map<String, ReadwriteSplittingDataSourceRule> buildDynamicReadwriteSplittingDataSourceRules(final ReadwriteSplittingDataSourceRuleConfiguration config,
+                                                                                                        final Collection<ShardingSphereRule> builtRules,
+                                                                                                        final ReadQueryLoadBalanceAlgorithm loadBalanceAlgorithm) {
+        Map<String, ReadwriteSplittingDataSourceRule> result = new LinkedHashMap<>();
+        List<String> readwriteInlineNames = new InlineExpressionParser(config.getName()).splitAndEvaluate();
+        List<String> autoAwareNames = new InlineExpressionParser(config.getDynamicStrategy().getAutoAwareDataSourceName()).splitAndEvaluate();
+        Preconditions.checkArgument(autoAwareNames.size() == readwriteInlineNames.size(), "Inline expression auto aware data source names size error");
+        for (int i = 0; i < readwriteInlineNames.size(); i++) {
+            ReadwriteSplittingDataSourceRuleConfiguration dynamicConfig = new ReadwriteSplittingDataSourceRuleConfiguration(readwriteInlineNames.get(i), null,
+                    new DynamicReadwriteSplittingStrategyConfiguration(autoAwareNames.get(i), config.getDynamicStrategy().getWriteDataSourceQueryEnabled()), config.getLoadBalancerName());
+            result.put(readwriteInlineNames.get(i), new ReadwriteSplittingDataSourceRule(dynamicConfig, loadBalanceAlgorithm, builtRules));
+        }
+        return result;
+    }
+
     /**
      * Get single data source rule.
      *
diff --git a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/test/java/org/apache/shardingsphere/readwritesplitting/checker/ReadwriteSplittingRuleConfigurationCheckerTest.java b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/test/java/org/apache/shardingsphere/readwritesplitting/checker/ReadwriteSplittingRuleConfigurationCheckerTest.java
index 9a6ef0ed6b8..59405db266b 100644
--- a/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/test/java/org/apache/shardingsphere/readwritesplitting/checker/ReadwriteSplittingRuleConfigurationCheckerTest.java
+++ b/shardingsphere-features/shardingsphere-readwrite-splitting/shardingsphere-readwrite-splitting-core/src/test/java/org/apache/shardingsphere/readwritesplitting/checker/ReadwriteSplittingRuleConfigurationCheckerTest.java
@@ -86,7 +86,7 @@ public final class ReadwriteSplittingRuleConfigurationCheckerTest {
     public void assertCheckWhenConfigInvalidWriteDataSource() {
         ReadwriteSplittingRuleConfiguration config = mock(ReadwriteSplittingRuleConfiguration.class);
         List<ReadwriteSplittingDataSourceRuleConfiguration> configurations = Arrays.asList(createDataSourceRuleConfig(
-                "write_ds", Arrays.asList("ds_0", "ds_1")), createDataSourceRuleConfig("write_ds", Arrays.asList("ds_2", "ds_3")));
+                "write_ds_0", Arrays.asList("ds_0", "ds_1")), createDataSourceRuleConfig("write_ds_1", Arrays.asList("ds_2", "ds_3")));
         when(config.getDataSources()).thenReturn(configurations);
         Optional<RuleConfigurationChecker> checker = RuleConfigurationCheckerFactory.findInstance(config);
         assertTrue(checker.isPresent());
@@ -139,6 +139,8 @@ public final class ReadwriteSplittingRuleConfigurationCheckerTest {
         Map<String, DataSource> result = new LinkedHashMap<>(2, 1);
         result.put("read_ds_0", mock(DataSource.class));
         result.put("read_ds_1", mock(DataSource.class));
+        result.put("write_ds_0", mock(DataSource.class));
+        result.put("write_ds_1", mock(DataSource.class));
         return result;
     }
 }
diff --git a/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/java/org/apache/shardingsphere/spring/boot/SpringBootStarterTest.java b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/java/org/apache/shardingsphere/spring/boot/SpringBootStarterTest.java
index 029e9052cee..5e924db6a9e 100644
--- a/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/java/org/apache/shardingsphere/spring/boot/SpringBootStarterTest.java
+++ b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/java/org/apache/shardingsphere/spring/boot/SpringBootStarterTest.java
@@ -74,9 +74,10 @@ public class SpringBootStarterTest {
     @Test
     public void assertDataSources() {
         Map<String, DataSource> dataSources = getContextManager(dataSource).getMetaDataContexts().getMetaData().getDatabase("foo_db").getResource().getDataSources();
-        assertThat(dataSources.size(), is(2));
-        assertTrue(dataSources.containsKey("ds0"));
-        assertTrue(dataSources.containsKey("ds1"));
+        assertThat(dataSources.size(), is(3));
+        assertTrue(dataSources.containsKey("read_ds_0"));
+        assertTrue(dataSources.containsKey("read_ds_1"));
+        assertTrue(dataSources.containsKey("write_ds"));
     }
     
     @Test
@@ -138,12 +139,12 @@ public class SpringBootStarterTest {
     }
     
     private void assertReadwriteSplittingRule(final ReadwriteSplittingRule actual) {
-        assertThat(actual.getDataSourceMapper(), is(Collections.singletonMap("readwrite_ds", Arrays.asList("write_ds", "ds0", "ds1"))));
+        assertThat(actual.getDataSourceMapper(), is(Collections.singletonMap("readwrite_ds", Arrays.asList("write_ds", "read_ds_0", "read_ds_1"))));
         ReadwriteSplittingDataSourceRule dataSourceRule = actual.getSingleDataSourceRule();
         assertThat(dataSourceRule.getName(), is("readwrite_ds"));
         StaticReadwriteSplittingStrategy staticReadwriteSplittingType = (StaticReadwriteSplittingStrategy) dataSourceRule.getReadwriteSplittingStrategy();
         assertThat(staticReadwriteSplittingType.getWriteDataSource(), is("write_ds"));
-        assertThat(staticReadwriteSplittingType.getReadDataSources(), is(Arrays.asList("ds0", "ds1")));
+        assertThat(staticReadwriteSplittingType.getReadDataSources(), is(Arrays.asList("read_ds_0", "read_ds_1")));
         assertThat(dataSourceRule.getLoadBalancer(), instanceOf(RandomReadQueryLoadBalanceAlgorithm.class));
     }
     
@@ -170,8 +171,8 @@ public class SpringBootStarterTest {
     
     private void assertShadowDataSourceMappings(final Map<String, ShadowDataSourceRule> actual) {
         assertThat(actual.size(), is(1));
-        assertThat(actual.get("shadow-data-source").getSourceDataSource(), is("ds0"));
-        assertThat(actual.get("shadow-data-source").getShadowDataSource(), is("ds1"));
+        assertThat(actual.get("shadow-data-source").getSourceDataSource(), is("read_ds_0"));
+        assertThat(actual.get("shadow-data-source").getShadowDataSource(), is("read_ds_1"));
     }
     
     private void assertShadowAlgorithms(final Map<String, ShadowAlgorithm> actual) {
diff --git a/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/java/org/apache/shardingsphere/spring/boot/jndi/SpringBootJNDIDataSourceTest.java b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/java/org/apache/shardingsphere/spring/boot/jndi/SpringBootJNDIDataSourceTest.java
index 0a1f2f527a8..7d893e14911 100644
--- a/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/java/org/apache/shardingsphere/spring/boot/jndi/SpringBootJNDIDataSourceTest.java
+++ b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/java/org/apache/shardingsphere/spring/boot/jndi/SpringBootJNDIDataSourceTest.java
@@ -54,14 +54,16 @@ public class SpringBootJNDIDataSourceTest {
         System.setProperty(Context.INITIAL_CONTEXT_FACTORY, InitialDataSourceInitialContextFactory.class.getName());
         InitialDataSourceInitialContextFactory.bind("java:comp/env/jdbc/ds0", new MockedDataSource());
         InitialDataSourceInitialContextFactory.bind("java:comp/env/jdbc/ds1", new MockedDataSource());
+        InitialDataSourceInitialContextFactory.bind("java:comp/env/jdbc/write_ds", new MockedDataSource());
     }
     
     @Test
     public void assertDataSources() {
         Map<String, DataSource> dataSources = getContextManager(dataSource).getMetaDataContexts().getMetaData().getDatabase("foo_db").getResource().getDataSources();
-        assertThat(dataSources.size(), is(2));
-        assertTrue(dataSources.containsKey("ds0"));
-        assertTrue(dataSources.containsKey("ds1"));
+        assertThat(dataSources.size(), is(3));
+        assertTrue(dataSources.containsKey("read_ds_0"));
+        assertTrue(dataSources.containsKey("read_ds_1"));
+        assertTrue(dataSources.containsKey("write_ds"));
     }
     
     @SneakyThrows(ReflectiveOperationException.class)
diff --git a/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/resources/application-jndi.properties b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/resources/application-jndi.properties
index 78d0d893de0..4abf7809b57 100644
--- a/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/resources/application-jndi.properties
+++ b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/resources/application-jndi.properties
@@ -15,8 +15,9 @@
 # limitations under the License.
 #
 
-spring.shardingsphere.datasource.names=ds0,ds1
-spring.shardingsphere.datasource.ds0.jndi-name=java:comp/env/jdbc/ds0
-spring.shardingsphere.datasource.ds1.jndi-name=jdbc/ds1
+spring.shardingsphere.datasource.names=write_ds,read_ds_0,read_ds_1
+spring.shardingsphere.datasource.write_ds.jndi-name=java:comp/env/jdbc/write_ds
+spring.shardingsphere.datasource.ds0.jndi-name=java:comp/env/jdbc/read_ds_0
+spring.shardingsphere.datasource.ds1.jndi-name=jdbc/read_ds_1
 
 spring.main.banner-mode=off
diff --git a/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/resources/application.properties b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/resources/application.properties
index 6a71135f75f..731b2a47bc0 100644
--- a/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/resources/application.properties
+++ b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-core-spring/shardingsphere-jdbc-core-spring-boot-starter/src/test/resources/application.properties
@@ -17,15 +17,16 @@
 
 spring.shardingsphere.database.name=foo_db
 
-spring.shardingsphere.datasource.names=ds${0..1}
+spring.shardingsphere.datasource.names=read_ds_${0..1},write_ds
 
-spring.shardingsphere.datasource.ds0.type=org.apache.shardingsphere.test.mock.MockedDataSource
-spring.shardingsphere.datasource.ds1.type=org.apache.shardingsphere.test.mock.MockedDataSource
+spring.shardingsphere.datasource.read_ds_0.type=org.apache.shardingsphere.test.mock.MockedDataSource
+spring.shardingsphere.datasource.read_ds_1.type=org.apache.shardingsphere.test.mock.MockedDataSource
+spring.shardingsphere.datasource.write_ds.type=org.apache.shardingsphere.test.mock.MockedDataSource
 
 spring.shardingsphere.rules.readwrite-splitting.load-balancers.random.type=RANDOM
 
 spring.shardingsphere.rules.readwrite-splitting.data-sources.readwrite_ds.static-strategy.write-data-source-name=write_ds
-spring.shardingsphere.rules.readwrite-splitting.data-sources.readwrite_ds.static-strategy.read-data-source-names=ds0,ds1
+spring.shardingsphere.rules.readwrite-splitting.data-sources.readwrite_ds.static-strategy.read-data-source-names=read_ds_0,read_ds_1
 spring.shardingsphere.rules.readwrite-splitting.data-sources.readwrite_ds.load-balancer-name=random
 
 spring.shardingsphere.rules.sharding.sharding-algorithms.databaseShardingAlgorithm.type=INLINE
@@ -52,8 +53,8 @@ spring.shardingsphere.rules.encrypt.tables.t_order.columns.pwd.plain-column=pwd_
 spring.shardingsphere.rules.encrypt.tables.t_order.columns.pwd.encryptor-name=aesEncryptor
 spring.shardingsphere.rules.encrypt.tables.t_order.columns.pwd.assisted-query-encryptor-name=aesEncryptor
 
-spring.shardingsphere.rules.shadow.data-sources.shadow-data-source.source-data-source-name=ds0
-spring.shardingsphere.rules.shadow.data-sources.shadow-data-source.shadow-data-source-name=ds1
+spring.shardingsphere.rules.shadow.data-sources.shadow-data-source.source-data-source-name=read_ds_0
+spring.shardingsphere.rules.shadow.data-sources.shadow-data-source.shadow-data-source-name=read_ds_1
 
 spring.shardingsphere.rules.shadow.tables.t_order.data-source-names=shadow-data-source
 spring.shardingsphere.rules.shadow.tables.t_order.shadow-algorithm-names=user-id-match-algorithm,order-id-match-algorithm,simple-hint-algorithm