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 2023/04/01 12:35:45 UTC

[shardingsphere] branch master updated: Refactor ReadwriteSplittingDataSourceRouter (#24941)

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

zhaojinchao 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 90c6bbb6120 Refactor ReadwriteSplittingDataSourceRouter (#24941)
90c6bbb6120 is described below

commit 90c6bbb61202c378820eec6fe13e8584a0b4b74d
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Sat Apr 1 20:35:37 2023 +0800

    Refactor ReadwriteSplittingDataSourceRouter (#24941)
---
 .../route/ReadwriteSplittingDataSourceRouter.java  | 74 ++++-----------------
 ...alifiedReadwriteSplittingDataSourceRouter.java} | 28 ++++----
 ...ReadwriteSplittingPrimaryDataSourceRouter.java} | 63 +++---------------
 ...riteSplittingTransactionalDataSourceRouter.java | 57 ++++++++++++++++
 ...StandardReadwriteSplittingDataSourceRouter.java | 48 ++++++++++++++
 .../filter/DisabledReadDataSourcesFilter.java      |  2 +-
 .../filter/ReadDataSourcesFilter.java              |  2 +-
 ...ng.route.standard.filter.ReadDataSourcesFilter} |  2 +-
 .../filter/DisabledReadDataSourcesFilterTest.java  | 75 ++++++++++++++++++++++
 9 files changed, 222 insertions(+), 129 deletions(-)

diff --git a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingDataSourceRouter.java b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingDataSourceRouter.java
index 2bd4f481076..e7019ff4be2 100644
--- a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingDataSourceRouter.java
+++ b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingDataSourceRouter.java
@@ -18,19 +18,16 @@
 package org.apache.shardingsphere.readwritesplitting.route;
 
 import lombok.RequiredArgsConstructor;
-import org.apache.shardingsphere.infra.binder.statement.CommonSQLStatementContext;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
-import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
 import org.apache.shardingsphere.infra.context.ConnectionContext;
-import org.apache.shardingsphere.infra.hint.HintManager;
-import org.apache.shardingsphere.infra.util.spi.ShardingSphereServiceLoader;
-import org.apache.shardingsphere.readwritesplitting.route.filter.ReadDataSourcesFilter;
+import org.apache.shardingsphere.readwritesplitting.route.qualified.QualifiedReadwriteSplittingDataSourceRouter;
+import org.apache.shardingsphere.readwritesplitting.route.qualified.type.QualifiedReadwriteSplittingPrimaryDataSourceRouter;
+import org.apache.shardingsphere.readwritesplitting.route.standard.StandardReadwriteSplittingDataSourceRouter;
+import org.apache.shardingsphere.readwritesplitting.route.qualified.type.QualifiedReadwriteSplittingTransactionalDataSourceRouter;
 import org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingDataSourceRule;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
-import org.apache.shardingsphere.sql.parser.sql.dialect.handler.dml.SelectStatementHandler;
 
-import java.util.List;
+import java.util.Arrays;
+import java.util.Collection;
 
 /**
  * Data source router for readwrite-splitting.
@@ -49,60 +46,15 @@ public final class ReadwriteSplittingDataSourceRouter {
      * @return data source name
      */
     public String route(final SQLStatementContext<?> sqlStatementContext) {
-        if (isPrimaryRoute(sqlStatementContext)) {
-            return rule.getWriteDataSource();
+        for (QualifiedReadwriteSplittingDataSourceRouter each : getQualifiedRouters(connectionContext)) {
+            if (each.isQualified(sqlStatementContext)) {
+                return each.route(rule);
+            }
         }
-        if (connectionContext.getTransactionContext().isInTransaction()) {
-            return routeInTransaction();
-        }
-        return routeWithLoadBalancer();
-    }
-    
-    private boolean isPrimaryRoute(final SQLStatementContext<?> sqlStatementContext) {
-        return isWriteRouteStatement(sqlStatementContext) || isHintWriteRouteOnly(sqlStatementContext);
-    }
-    
-    private boolean isWriteRouteStatement(final SQLStatementContext<?> sqlStatementContext) {
-        SQLStatement sqlStatement = sqlStatementContext.getSqlStatement();
-        return containsLockSegment(sqlStatement) || containsLastInsertIdProjection(sqlStatementContext) || !(sqlStatement instanceof SelectStatement);
-    }
-    
-    private boolean containsLockSegment(final SQLStatement sqlStatement) {
-        return sqlStatement instanceof SelectStatement && SelectStatementHandler.getLockSegment((SelectStatement) sqlStatement).isPresent();
-    }
-    
-    private boolean containsLastInsertIdProjection(final SQLStatementContext<?> sqlStatementContext) {
-        return sqlStatementContext instanceof SelectStatementContext && ((SelectStatementContext) sqlStatementContext).getProjectionsContext().isContainsLastInsertIdProjection();
+        return new StandardReadwriteSplittingDataSourceRouter().route(rule);
     }
     
-    private boolean isHintWriteRouteOnly(final SQLStatementContext<?> sqlStatementContext) {
-        return HintManager.isWriteRouteOnly() || sqlStatementContext instanceof CommonSQLStatementContext && ((CommonSQLStatementContext<?>) sqlStatementContext).isHintWriteRouteOnly();
-    }
-    
-    private String routeInTransaction() {
-        switch (rule.getTransactionalReadQueryStrategy()) {
-            case FIXED:
-                if (null == connectionContext.getTransactionContext().getReadWriteSplitReplicaRoute()) {
-                    connectionContext.getTransactionContext().setReadWriteSplitReplicaRoute(routeWithLoadBalancer());
-                }
-                return connectionContext.getTransactionContext().getReadWriteSplitReplicaRoute();
-            case DYNAMIC:
-                return routeWithLoadBalancer();
-            case PRIMARY:
-            default:
-                return rule.getWriteDataSource();
-        }
-    }
-    
-    private String routeWithLoadBalancer() {
-        return rule.getLoadBalancer().getDataSource(rule.getName(), rule.getWriteDataSource(), getFilteredReadDataSources());
-    }
-    
-    private List<String> getFilteredReadDataSources() {
-        List<String> result = rule.getReadwriteSplittingStrategy().getReadDataSources();
-        for (ReadDataSourcesFilter each : ShardingSphereServiceLoader.getServiceInstances(ReadDataSourcesFilter.class)) {
-            result = each.filter(rule, result);
-        }
-        return result;
+    private Collection<QualifiedReadwriteSplittingDataSourceRouter> getQualifiedRouters(final ConnectionContext connectionContext) {
+        return Arrays.asList(new QualifiedReadwriteSplittingPrimaryDataSourceRouter(), new QualifiedReadwriteSplittingTransactionalDataSourceRouter(connectionContext));
     }
 }
diff --git a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/filter/ReadDataSourcesFilter.java b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/qualified/QualifiedReadwriteSplittingDataSourceRouter.java
similarity index 57%
copy from features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/filter/ReadDataSourcesFilter.java
copy to features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/qualified/QualifiedReadwriteSplittingDataSourceRouter.java
index 04814bf3ddc..d7f53219ec1 100644
--- a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/filter/ReadDataSourcesFilter.java
+++ b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/qualified/QualifiedReadwriteSplittingDataSourceRouter.java
@@ -15,25 +15,29 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.readwritesplitting.route.filter;
+package org.apache.shardingsphere.readwritesplitting.route.qualified;
 
-import org.apache.shardingsphere.infra.util.spi.annotation.SingletonSPI;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingDataSourceRule;
 
-import java.util.List;
-
 /**
- * Read data sources filter.
+ * Qualified data source router for readwrite-splitting.
  */
-@SingletonSPI
-public interface ReadDataSourcesFilter {
+public interface QualifiedReadwriteSplittingDataSourceRouter {
     
     /**
-     * Filter replica data sources.
+     * Judge whether qualified to route.
      * 
-     * @param rule readwrite-splitting data source rule
-     * @param toBeFilteredReadDataSources to be filtered read data sources
-     * @return filtered read data sources
+     * @param sqlStatementContext SQL statement context
+     * @return qualified to route or not
+     */
+    boolean isQualified(SQLStatementContext<?> sqlStatementContext);
+    
+    /**
+     * Route to data source.
+     *
+     * @param rule Readwrite-splitting data source rule
+     * @return routed data source name
      */
-    List<String> filter(ReadwriteSplittingDataSourceRule rule, List<String> toBeFilteredReadDataSources);
+    String route(ReadwriteSplittingDataSourceRule rule);
 }
diff --git a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingDataSourceRouter.java b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/qualified/type/QualifiedReadwriteSplittingPrimaryDataSourceRouter.java
similarity index 55%
copy from features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingDataSourceRouter.java
copy to features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/qualified/type/QualifiedReadwriteSplittingPrimaryDataSourceRouter.java
index 2bd4f481076..4302728c428 100644
--- a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingDataSourceRouter.java
+++ b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/qualified/type/QualifiedReadwriteSplittingPrimaryDataSourceRouter.java
@@ -15,47 +15,26 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.readwritesplitting.route;
+package org.apache.shardingsphere.readwritesplitting.route.qualified.type;
 
-import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.infra.binder.statement.CommonSQLStatementContext;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
-import org.apache.shardingsphere.infra.context.ConnectionContext;
 import org.apache.shardingsphere.infra.hint.HintManager;
-import org.apache.shardingsphere.infra.util.spi.ShardingSphereServiceLoader;
-import org.apache.shardingsphere.readwritesplitting.route.filter.ReadDataSourcesFilter;
+import org.apache.shardingsphere.readwritesplitting.route.qualified.QualifiedReadwriteSplittingDataSourceRouter;
 import org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingDataSourceRule;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.handler.dml.SelectStatementHandler;
 
-import java.util.List;
-
 /**
- * Data source router for readwrite-splitting.
+ * Qualified data source primary router for readwrite-splitting.
  */
-@RequiredArgsConstructor
-public final class ReadwriteSplittingDataSourceRouter {
-    
-    private final ReadwriteSplittingDataSourceRule rule;
+public final class QualifiedReadwriteSplittingPrimaryDataSourceRouter implements QualifiedReadwriteSplittingDataSourceRouter {
     
-    private final ConnectionContext connectionContext;
-    
-    /**
-     * Route.
-     * 
-     * @param sqlStatementContext SQL statement context
-     * @return data source name
-     */
-    public String route(final SQLStatementContext<?> sqlStatementContext) {
-        if (isPrimaryRoute(sqlStatementContext)) {
-            return rule.getWriteDataSource();
-        }
-        if (connectionContext.getTransactionContext().isInTransaction()) {
-            return routeInTransaction();
-        }
-        return routeWithLoadBalancer();
+    @Override
+    public boolean isQualified(final SQLStatementContext<?> sqlStatementContext) {
+        return isPrimaryRoute(sqlStatementContext);
     }
     
     private boolean isPrimaryRoute(final SQLStatementContext<?> sqlStatementContext) {
@@ -79,30 +58,8 @@ public final class ReadwriteSplittingDataSourceRouter {
         return HintManager.isWriteRouteOnly() || sqlStatementContext instanceof CommonSQLStatementContext && ((CommonSQLStatementContext<?>) sqlStatementContext).isHintWriteRouteOnly();
     }
     
-    private String routeInTransaction() {
-        switch (rule.getTransactionalReadQueryStrategy()) {
-            case FIXED:
-                if (null == connectionContext.getTransactionContext().getReadWriteSplitReplicaRoute()) {
-                    connectionContext.getTransactionContext().setReadWriteSplitReplicaRoute(routeWithLoadBalancer());
-                }
-                return connectionContext.getTransactionContext().getReadWriteSplitReplicaRoute();
-            case DYNAMIC:
-                return routeWithLoadBalancer();
-            case PRIMARY:
-            default:
-                return rule.getWriteDataSource();
-        }
-    }
-    
-    private String routeWithLoadBalancer() {
-        return rule.getLoadBalancer().getDataSource(rule.getName(), rule.getWriteDataSource(), getFilteredReadDataSources());
-    }
-    
-    private List<String> getFilteredReadDataSources() {
-        List<String> result = rule.getReadwriteSplittingStrategy().getReadDataSources();
-        for (ReadDataSourcesFilter each : ShardingSphereServiceLoader.getServiceInstances(ReadDataSourcesFilter.class)) {
-            result = each.filter(rule, result);
-        }
-        return result;
+    @Override
+    public String route(final ReadwriteSplittingDataSourceRule rule) {
+        return rule.getWriteDataSource();
     }
 }
diff --git a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/qualified/type/QualifiedReadwriteSplittingTransactionalDataSourceRouter.java b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/qualified/type/QualifiedReadwriteSplittingTransactionalDataSourceRouter.java
new file mode 100644
index 00000000000..08fd2cf7b23
--- /dev/null
+++ b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/qualified/type/QualifiedReadwriteSplittingTransactionalDataSourceRouter.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shardingsphere.readwritesplitting.route.qualified.type;
+
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
+import org.apache.shardingsphere.infra.context.ConnectionContext;
+import org.apache.shardingsphere.readwritesplitting.route.qualified.QualifiedReadwriteSplittingDataSourceRouter;
+import org.apache.shardingsphere.readwritesplitting.route.standard.StandardReadwriteSplittingDataSourceRouter;
+import org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingDataSourceRule;
+
+/**
+ * Qualified data source transactional router for readwrite-splitting.
+ */
+@RequiredArgsConstructor
+public final class QualifiedReadwriteSplittingTransactionalDataSourceRouter implements QualifiedReadwriteSplittingDataSourceRouter {
+    
+    private final ConnectionContext connectionContext;
+    
+    private final StandardReadwriteSplittingDataSourceRouter standardRouter = new StandardReadwriteSplittingDataSourceRouter();
+    
+    @Override
+    public boolean isQualified(final SQLStatementContext<?> sqlStatementContext) {
+        return connectionContext.getTransactionContext().isInTransaction();
+    }
+    
+    @Override
+    public String route(final ReadwriteSplittingDataSourceRule rule) {
+        switch (rule.getTransactionalReadQueryStrategy()) {
+            case FIXED:
+                if (null == connectionContext.getTransactionContext().getReadWriteSplitReplicaRoute()) {
+                    connectionContext.getTransactionContext().setReadWriteSplitReplicaRoute(standardRouter.route(rule));
+                }
+                return connectionContext.getTransactionContext().getReadWriteSplitReplicaRoute();
+            case DYNAMIC:
+                return standardRouter.route(rule);
+            case PRIMARY:
+            default:
+                return rule.getWriteDataSource();
+        }
+    }
+}
diff --git a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/standard/StandardReadwriteSplittingDataSourceRouter.java b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/standard/StandardReadwriteSplittingDataSourceRouter.java
new file mode 100644
index 00000000000..fbd01ac03ae
--- /dev/null
+++ b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/standard/StandardReadwriteSplittingDataSourceRouter.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shardingsphere.readwritesplitting.route.standard;
+
+import org.apache.shardingsphere.infra.util.spi.ShardingSphereServiceLoader;
+import org.apache.shardingsphere.readwritesplitting.route.standard.filter.ReadDataSourcesFilter;
+import org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingDataSourceRule;
+
+import java.util.List;
+
+/**
+ * Standard data source router for readwrite-splitting.
+ */
+public final class StandardReadwriteSplittingDataSourceRouter {
+    
+    /**
+     * Route to data source.
+     *
+     * @param rule Readwrite-splitting data source rule
+     * @return routed data source name
+     */
+    public String route(final ReadwriteSplittingDataSourceRule rule) {
+        return rule.getLoadBalancer().getDataSource(rule.getName(), rule.getWriteDataSource(), getFilteredReadDataSources(rule));
+    }
+    
+    private List<String> getFilteredReadDataSources(final ReadwriteSplittingDataSourceRule rule) {
+        List<String> result = rule.getReadwriteSplittingStrategy().getReadDataSources();
+        for (ReadDataSourcesFilter each : ShardingSphereServiceLoader.getServiceInstances(ReadDataSourcesFilter.class)) {
+            result = each.filter(rule, result);
+        }
+        return result;
+    }
+}
diff --git a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/filter/DisabledReadDataSourcesFilter.java b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/standard/filter/DisabledReadDataSourcesFilter.java
similarity index 94%
rename from features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/filter/DisabledReadDataSourcesFilter.java
rename to features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/standard/filter/DisabledReadDataSourcesFilter.java
index fcec1cda1ef..31f552952fa 100644
--- a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/filter/DisabledReadDataSourcesFilter.java
+++ b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/standard/filter/DisabledReadDataSourcesFilter.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.readwritesplitting.route.filter;
+package org.apache.shardingsphere.readwritesplitting.route.standard.filter;
 
 import org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingDataSourceRule;
 
diff --git a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/filter/ReadDataSourcesFilter.java b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/standard/filter/ReadDataSourcesFilter.java
similarity index 94%
rename from features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/filter/ReadDataSourcesFilter.java
rename to features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/standard/filter/ReadDataSourcesFilter.java
index 04814bf3ddc..db6af150018 100644
--- a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/filter/ReadDataSourcesFilter.java
+++ b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/standard/filter/ReadDataSourcesFilter.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.readwritesplitting.route.filter;
+package org.apache.shardingsphere.readwritesplitting.route.standard.filter;
 
 import org.apache.shardingsphere.infra.util.spi.annotation.SingletonSPI;
 import org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingDataSourceRule;
diff --git a/features/readwrite-splitting/core/src/main/resources/META-INF/services/org.apache.shardingsphere.readwritesplitting.route.filter.ReadDataSourcesFilter b/features/readwrite-splitting/core/src/main/resources/META-INF/services/org.apache.shardingsphere.readwritesplitting.route.standard.filter.ReadDataSourcesFilter
similarity index 89%
rename from features/readwrite-splitting/core/src/main/resources/META-INF/services/org.apache.shardingsphere.readwritesplitting.route.filter.ReadDataSourcesFilter
rename to features/readwrite-splitting/core/src/main/resources/META-INF/services/org.apache.shardingsphere.readwritesplitting.route.standard.filter.ReadDataSourcesFilter
index a441670e920..f5ab693ac77 100644
--- a/features/readwrite-splitting/core/src/main/resources/META-INF/services/org.apache.shardingsphere.readwritesplitting.route.filter.ReadDataSourcesFilter
+++ b/features/readwrite-splitting/core/src/main/resources/META-INF/services/org.apache.shardingsphere.readwritesplitting.route.standard.filter.ReadDataSourcesFilter
@@ -15,4 +15,4 @@
 # limitations under the License.
 #
 
-org.apache.shardingsphere.readwritesplitting.route.filter.DisabledReadDataSourcesFilter
+org.apache.shardingsphere.readwritesplitting.route.standard.filter.DisabledReadDataSourcesFilter
diff --git a/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/standard/filter/DisabledReadDataSourcesFilterTest.java b/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/standard/filter/DisabledReadDataSourcesFilterTest.java
new file mode 100644
index 00000000000..7c8302739be
--- /dev/null
+++ b/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/standard/filter/DisabledReadDataSourcesFilterTest.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.shardingsphere.readwritesplitting.route.standard.filter;
+
+import org.apache.shardingsphere.readwritesplitting.algorithm.loadbalance.RandomReadQueryLoadBalanceAlgorithm;
+import org.apache.shardingsphere.readwritesplitting.api.rule.ReadwriteSplittingDataSourceRuleConfiguration;
+import org.apache.shardingsphere.readwritesplitting.api.strategy.StaticReadwriteSplittingStrategyConfiguration;
+import org.apache.shardingsphere.readwritesplitting.api.transaction.TransactionalReadQueryStrategy;
+import org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingDataSourceRule;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+class DisabledReadDataSourcesFilterTest {
+    
+    private ReadwriteSplittingDataSourceRule rule;
+    
+    @BeforeEach
+    void setUp() {
+        rule = new ReadwriteSplittingDataSourceRule(
+                new ReadwriteSplittingDataSourceRuleConfiguration("test_pr",
+                        new StaticReadwriteSplittingStrategyConfiguration("write_ds", Arrays.asList("read_ds_0", "read_ds_1")), null, null),
+                TransactionalReadQueryStrategy.DYNAMIC, new RandomReadQueryLoadBalanceAlgorithm());
+    }
+    
+    @Test
+    void assertGetReadDataSourceNamesWithoutDisabledDataSourceNames() {
+        assertThat(new DisabledReadDataSourcesFilter().filter(rule, Arrays.asList("read_ds_0", "read_ds_1")), is(Arrays.asList("read_ds_0", "read_ds_1")));
+    }
+    
+    @Test
+    void assertGetReadDataSourceNamesWithDisabledDataSourceNames() {
+        rule.updateDisabledDataSourceNames("read_ds_0", true);
+        assertThat(new DisabledReadDataSourcesFilter().filter(rule, Arrays.asList("read_ds_0", "read_ds_1")), is(Collections.singletonList("read_ds_1")));
+    }
+    
+    @Test
+    void assertUpdateDisabledDataSourceNamesForDisabled() {
+        rule.updateDisabledDataSourceNames("read_ds_0", true);
+        assertThat(new DisabledReadDataSourcesFilter().filter(rule, Arrays.asList("read_ds_0", "read_ds_1")), is(Collections.singletonList("read_ds_1")));
+    }
+    
+    @Test
+    void assertUpdateDisabledDataSourceNamesForEnabled() {
+        rule.updateDisabledDataSourceNames("read_ds_0", true);
+        rule.updateDisabledDataSourceNames("read_ds_0", false);
+        assertThat(new DisabledReadDataSourcesFilter().filter(rule, Arrays.asList("read_ds_0", "read_ds_1")), is(Arrays.asList("read_ds_0", "read_ds_1")));
+    }
+    
+    @Test
+    void assertGetEnabledReplicaDataSources() {
+        rule.updateDisabledDataSourceNames("read_ds_0", true);
+        assertThat(new DisabledReadDataSourcesFilter().filter(rule, Arrays.asList("read_ds_0", "read_ds_1")), is(Collections.singletonList("read_ds_1")));
+    }
+}