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

terrymanu 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 fbe03f42872 Refactor MCP resource handler tests (#38914)
fbe03f42872 is described below

commit fbe03f42872e49abbe77492da669de375a8b5e8a
Author: Liang Zhang <[email protected]>
AuthorDate: Thu Jun 25 12:57:14 2026 +0800

    Refactor MCP resource handler tests (#38914)
    
    Delete the unused sharding ResourceHandler shim and its aggregate test.
    Replace aggregate Encrypt, Mask, Broadcast, and Readwrite-splitting
    resource handler tests with direct tests for each concrete handler.
---
 .../handler/BroadcastResourceHandlerTest.java      |  79 ------
 .../handler/BroadcastRuleCountHandlerTest.java     |  63 +++++
 .../handler/BroadcastRulesHandlerTest.java         |  62 ++++
 .../handler/BroadcastTableRuleHandlerTest.java     |  65 +++++
 .../handler/EncryptAlgorithmsHandlerTest.java      |  65 +++++
 .../handler/EncryptResourceHandlerTest.java        |  79 ------
 .../resource/handler/EncryptRuleHandlerTest.java   |  66 +++++
 .../resource/handler/EncryptRulesHandlerTest.java  |  65 +++++
 .../handler/MaskAlgorithmsHandlerTest.java         |  65 +++++
 .../resource/handler/MaskResourceHandlerTest.java  |  73 -----
 .../mask/resource/handler/MaskRuleHandlerTest.java |  66 +++++
 .../resource/handler/MaskRulesHandlerTest.java     |  65 +++++
 .../LoadBalanceAlgorithmPluginsHandlerTest.java    |  62 ++++
 .../ReadwriteSplittingResourceHandlerTest.java     |  87 ------
 .../ReadwriteSplittingRuleCountHandlerTest.java    |  63 +++++
 .../handler/ReadwriteSplittingRuleHandlerTest.java |  63 +++++
 .../ReadwriteSplittingRuleStatusHandlerTest.java   |  63 +++++
 .../ReadwriteSplittingRulesHandlerTest.java        |  62 ++++
 .../ReadwriteSplittingStatusHandlerTest.java       |  63 +++++
 .../resource/handler/ShardingResourceHandler.java  | 312 ---------------------
 .../handler/ShardingResourceHandlerTest.java       | 155 ----------
 21 files changed, 958 insertions(+), 785 deletions(-)

diff --git 
a/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/resource/handler/BroadcastResourceHandlerTest.java
 
b/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/resource/handler/BroadcastResourceHandlerTest.java
deleted file mode 100644
index e95cbefd106..00000000000
--- 
a/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/resource/handler/BroadcastResourceHandlerTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.mcp.feature.broadcast.resource.handler;
-
-import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
-import org.apache.shardingsphere.mcp.api.resource.MCPResourceHandler;
-import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
-import 
org.apache.shardingsphere.mcp.feature.broadcast.tool.service.BroadcastRuleInspectionService;
-import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
-import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
-
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-class BroadcastResourceHandlerTest {
-    
-    @ParameterizedTest(name = "{0}")
-    @MethodSource("assertHandleArguments")
-    void assertHandle(final String name, final 
MCPResourceHandler<MCPDatabaseHandlerContext> handler, final List<Map<String, 
Object>> rows,
-                      final Map<String, String> uriVariables, final String 
expectedSelfUri, final String expectedParentUri) {
-        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
-        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
-        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
-        when(queryFacade.getDatabaseType("logic_db")).thenReturn("MySQL");
-        MCPResponse actual = handler.handle(databaseContext, new 
MCPUriVariables(uriVariables));
-        assertThat(((List<?>) actual.toPayload().get("items")).size(), 
is(rows.size()));
-        assertThat(actual.toPayload().get("self_uri"), is(expectedSelfUri));
-        if (!expectedParentUri.isEmpty()) {
-            assertThat(((Map<?, ?>) 
actual.toPayload().get("parent_resource")).get("uri"), is(expectedParentUri));
-        }
-    }
-    
-    private static Stream<Arguments> assertHandleArguments() {
-        List<Map<String, Object>> rules = List.of(Map.of("broadcast_table", 
"t_order"), Map.of("broadcast_table", "t_order_item"));
-        List<Map<String, Object>> count = List.of(Map.of("rule_name", 
"broadcast_table", "count", 1));
-        BroadcastRuleInspectionService rulesService = 
mock(BroadcastRuleInspectionService.class);
-        BroadcastRuleInspectionService tableRuleService = 
mock(BroadcastRuleInspectionService.class);
-        BroadcastRuleInspectionService countService = 
mock(BroadcastRuleInspectionService.class);
-        when(rulesService.queryBroadcastRules(any(), 
eq("logic_db"))).thenReturn(rules);
-        when(tableRuleService.queryBroadcastRules(any(), 
eq("logic_db"))).thenReturn(rules);
-        when(countService.queryBroadcastRuleCount(any(), 
eq("logic_db"))).thenReturn(count);
-        return Stream.of(
-                Arguments.of("broadcast rules", new 
BroadcastRulesHandler(rulesService), rules,
-                        Map.of("database", "logic_db"), 
"shardingsphere://features/broadcast/databases/logic_db/rules", ""),
-                Arguments.of("broadcast table rule", new 
BroadcastTableRuleHandler(tableRuleService), List.of(Map.of("broadcast_table", 
"t_order")),
-                        Map.of("database", "logic_db", "table", "t_order"), 
"shardingsphere://features/broadcast/databases/logic_db/tables/t_order/rule",
-                        
"shardingsphere://features/broadcast/databases/logic_db/rules"),
-                Arguments.of("broadcast rule count", new 
BroadcastRuleCountHandler(countService), count,
-                        Map.of("database", "logic_db"),
-                        
"shardingsphere://features/broadcast/databases/logic_db/rule-count",
-                        
"shardingsphere://features/broadcast/databases/logic_db/rules"));
-    }
-}
diff --git 
a/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/resource/handler/BroadcastRuleCountHandlerTest.java
 
b/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/resource/handler/BroadcastRuleCountHandlerTest.java
new file mode 100644
index 00000000000..18338c19f6e
--- /dev/null
+++ 
b/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/resource/handler/BroadcastRuleCountHandlerTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.mcp.feature.broadcast.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import 
org.apache.shardingsphere.mcp.feature.broadcast.BroadcastFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.broadcast.tool.service.BroadcastRuleInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class BroadcastRuleCountHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new BroadcastRuleCountHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new BroadcastRuleCountHandler().getResourceUriTemplate(), 
is(BroadcastFeatureDefinition.RULE_COUNT_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() {
+        BroadcastRuleInspectionService ruleInspectionService = 
mock(BroadcastRuleInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        when(ruleInspectionService.queryBroadcastRuleCount(queryFacade, 
"logic_db")).thenReturn(List.of(Map.of("rule_count", 2)));
+        MCPResponse actual = new 
BroadcastRuleCountHandler(ruleInspectionService).handle(databaseContext, new 
MCPUriVariables(Map.of("database", "logic_db")));
+        verify(ruleInspectionService).queryBroadcastRuleCount(queryFacade, 
"logic_db");
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(1));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/broadcast/databases/logic_db/rule-count"));
+        assertThat(((Map<?, ?>) 
actual.toPayload().get("parent_resource")).get("uri"), 
is("shardingsphere://features/broadcast/databases/logic_db/rules"));
+    }
+}
diff --git 
a/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/resource/handler/BroadcastRulesHandlerTest.java
 
b/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/resource/handler/BroadcastRulesHandlerTest.java
new file mode 100644
index 00000000000..15d4b4aaaa9
--- /dev/null
+++ 
b/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/resource/handler/BroadcastRulesHandlerTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.mcp.feature.broadcast.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import 
org.apache.shardingsphere.mcp.feature.broadcast.BroadcastFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.broadcast.tool.service.BroadcastRuleInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class BroadcastRulesHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new BroadcastRulesHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new BroadcastRulesHandler().getResourceUriTemplate(), 
is(BroadcastFeatureDefinition.RULES_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() {
+        BroadcastRuleInspectionService ruleInspectionService = 
mock(BroadcastRuleInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        when(ruleInspectionService.queryBroadcastRules(queryFacade, 
"logic_db")).thenReturn(List.of(Map.of("broadcast_table", "t_order"), 
Map.of("broadcast_table", "t_order_item")));
+        MCPResponse actual = new 
BroadcastRulesHandler(ruleInspectionService).handle(databaseContext, new 
MCPUriVariables(Map.of("database", "logic_db")));
+        verify(ruleInspectionService).queryBroadcastRules(queryFacade, 
"logic_db");
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(2));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/broadcast/databases/logic_db/rules"));
+    }
+}
diff --git 
a/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/resource/handler/BroadcastTableRuleHandlerTest.java
 
b/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/resource/handler/BroadcastTableRuleHandlerTest.java
new file mode 100644
index 00000000000..38d53254e60
--- /dev/null
+++ 
b/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/resource/handler/BroadcastTableRuleHandlerTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.mcp.feature.broadcast.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import 
org.apache.shardingsphere.mcp.feature.broadcast.BroadcastFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.broadcast.tool.service.BroadcastRuleInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class BroadcastTableRuleHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new BroadcastTableRuleHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new BroadcastTableRuleHandler().getResourceUriTemplate(), 
is(BroadcastFeatureDefinition.TABLE_RULE_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() {
+        BroadcastRuleInspectionService ruleInspectionService = 
mock(BroadcastRuleInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        when(queryFacade.getDatabaseType("logic_db")).thenReturn("MySQL");
+        when(ruleInspectionService.queryBroadcastRules(queryFacade, 
"logic_db")).thenReturn(List.of(Map.of("broadcast_table", "t_order"), 
Map.of("broadcast_table", "t_order_item")));
+        MCPResponse actual = new 
BroadcastTableRuleHandler(ruleInspectionService).handle(databaseContext, new 
MCPUriVariables(Map.of("database", "logic_db", "table", "t_order")));
+        verify(ruleInspectionService).queryBroadcastRules(queryFacade, 
"logic_db");
+        List<?> items = (List<?>) actual.toPayload().get("items");
+        assertThat(items.size(), is(1));
+        assertThat(((Map<?, ?>) items.getFirst()).get("broadcast_table"), 
is("t_order"));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/broadcast/databases/logic_db/tables/t_order/rule"));
+        assertThat(((Map<?, ?>) 
actual.toPayload().get("parent_resource")).get("uri"), 
is("shardingsphere://features/broadcast/databases/logic_db/rules"));
+    }
+}
diff --git 
a/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/resource/handler/EncryptAlgorithmsHandlerTest.java
 
b/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/resource/handler/EncryptAlgorithmsHandlerTest.java
new file mode 100644
index 00000000000..612d7730102
--- /dev/null
+++ 
b/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/resource/handler/EncryptAlgorithmsHandlerTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.mcp.feature.encrypt.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import org.apache.shardingsphere.mcp.feature.encrypt.EncryptFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.encrypt.tool.service.EncryptRuleInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+import org.mockito.internal.configuration.plugins.Plugins;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class EncryptAlgorithmsHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new EncryptAlgorithmsHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new EncryptAlgorithmsHandler().getResourceUriTemplate(), 
is(EncryptFeatureDefinition.ALGORITHMS_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() throws ReflectiveOperationException {
+        EncryptAlgorithmsHandler handler = new EncryptAlgorithmsHandler();
+        EncryptRuleInspectionService ruleInspectionService = 
mock(EncryptRuleInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        
when(ruleInspectionService.queryEncryptAlgorithms(queryFacade)).thenReturn(List.of(Map.of("type",
 "AES")));
+        
Plugins.getMemberAccessor().set(EncryptAlgorithmsHandler.class.getDeclaredField("ruleInspectionService"),
 handler, ruleInspectionService);
+        MCPResponse actual = handler.handle(databaseContext, new 
MCPUriVariables(Map.of()));
+        verify(ruleInspectionService).queryEncryptAlgorithms(queryFacade);
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(1));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/encrypt/algorithms"));
+    }
+}
diff --git 
a/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/resource/handler/EncryptResourceHandlerTest.java
 
b/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/resource/handler/EncryptResourceHandlerTest.java
deleted file mode 100644
index 372a626331c..00000000000
--- 
a/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/resource/handler/EncryptResourceHandlerTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.mcp.feature.encrypt.resource.handler;
-
-import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
-import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
-import 
org.apache.shardingsphere.mcp.feature.encrypt.tool.service.EncryptRuleInspectionService;
-import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
-import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
-import org.junit.jupiter.api.Test;
-import org.mockito.internal.configuration.plugins.Plugins;
-
-import java.util.List;
-import java.util.Map;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-class EncryptResourceHandlerTest {
-    
-    @Test
-    void assertHandleEncryptAlgorithms() throws ReflectiveOperationException {
-        EncryptAlgorithmsHandler handler = new EncryptAlgorithmsHandler();
-        EncryptRuleInspectionService ruleInspectionService = 
mock(EncryptRuleInspectionService.class);
-        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
-        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
-        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
-        
when(ruleInspectionService.queryEncryptAlgorithms(queryFacade)).thenReturn(List.of(Map.of("type",
 "AES")));
-        Plugins.getMemberAccessor().set(((Object) 
handler).getClass().getDeclaredField("ruleInspectionService"), handler, 
ruleInspectionService);
-        MCPResponse actual = handler.handle(databaseContext, new 
MCPUriVariables(Map.of()));
-        assertThat(((List<?>) actual.toPayload().get("items")).size(), is(1));
-        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/encrypt/algorithms"));
-    }
-    
-    @Test
-    void assertHandleEncryptRules() throws ReflectiveOperationException {
-        EncryptRulesHandler handler = new EncryptRulesHandler();
-        EncryptRuleInspectionService ruleInspectionService = 
mock(EncryptRuleInspectionService.class);
-        when(ruleInspectionService.queryEncryptRules(any(), 
any())).thenReturn(List.of(Map.of("logic_column", "phone")));
-        Plugins.getMemberAccessor().set(((Object) 
handler).getClass().getDeclaredField("ruleInspectionService"), handler, 
ruleInspectionService);
-        MCPResponse actual = 
handler.handle(mock(MCPDatabaseHandlerContext.class), new 
MCPUriVariables(Map.of("database", "logic_db")));
-        verify(ruleInspectionService).queryEncryptRules(any(), eq("logic_db"));
-        assertThat(((List<?>) actual.toPayload().get("items")).size(), is(1));
-        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/encrypt/databases/logic_db/rules"));
-    }
-    
-    @Test
-    void assertHandleEncryptRule() throws ReflectiveOperationException {
-        EncryptRuleHandler handler = new EncryptRuleHandler();
-        EncryptRuleInspectionService ruleInspectionService = 
mock(EncryptRuleInspectionService.class);
-        when(ruleInspectionService.queryEncryptRules(any(), any(), 
any())).thenReturn(List.of(Map.of("logic_column", "phone")));
-        Plugins.getMemberAccessor().set(((Object) 
handler).getClass().getDeclaredField("ruleInspectionService"), handler, 
ruleInspectionService);
-        MCPResponse actual = 
handler.handle(mock(MCPDatabaseHandlerContext.class), new 
MCPUriVariables(Map.of("database", "logic_db", "table", "orders")));
-        verify(ruleInspectionService).queryEncryptRules(any(), eq("logic_db"), 
eq("orders"));
-        assertThat(((List<?>) actual.toPayload().get("items")).size(), is(1));
-        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/encrypt/databases/logic_db/tables/orders/rules"));
-        assertThat(((Map<?, ?>) 
actual.toPayload().get("parent_resource")).get("uri"), 
is("shardingsphere://features/encrypt/databases/logic_db/rules"));
-    }
-}
diff --git 
a/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/resource/handler/EncryptRuleHandlerTest.java
 
b/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/resource/handler/EncryptRuleHandlerTest.java
new file mode 100644
index 00000000000..d8c92b24be4
--- /dev/null
+++ 
b/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/resource/handler/EncryptRuleHandlerTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.mcp.feature.encrypt.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import org.apache.shardingsphere.mcp.feature.encrypt.EncryptFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.encrypt.tool.service.EncryptRuleInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+import org.mockito.internal.configuration.plugins.Plugins;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class EncryptRuleHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new EncryptRuleHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new EncryptRuleHandler().getResourceUriTemplate(), 
is(EncryptFeatureDefinition.RULE_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() throws ReflectiveOperationException {
+        EncryptRuleHandler handler = new EncryptRuleHandler();
+        EncryptRuleInspectionService ruleInspectionService = 
mock(EncryptRuleInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        when(ruleInspectionService.queryEncryptRules(queryFacade, "logic_db", 
"orders")).thenReturn(List.of(Map.of("logic_column", "phone")));
+        
Plugins.getMemberAccessor().set(EncryptRuleHandler.class.getDeclaredField("ruleInspectionService"),
 handler, ruleInspectionService);
+        MCPResponse actual = handler.handle(databaseContext, new 
MCPUriVariables(Map.of("database", "logic_db", "table", "orders")));
+        verify(ruleInspectionService).queryEncryptRules(queryFacade, 
"logic_db", "orders");
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(1));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/encrypt/databases/logic_db/tables/orders/rules"));
+        assertThat(((Map<?, ?>) 
actual.toPayload().get("parent_resource")).get("uri"), 
is("shardingsphere://features/encrypt/databases/logic_db/rules"));
+    }
+}
diff --git 
a/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/resource/handler/EncryptRulesHandlerTest.java
 
b/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/resource/handler/EncryptRulesHandlerTest.java
new file mode 100644
index 00000000000..86199f66e34
--- /dev/null
+++ 
b/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/resource/handler/EncryptRulesHandlerTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.mcp.feature.encrypt.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import org.apache.shardingsphere.mcp.feature.encrypt.EncryptFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.encrypt.tool.service.EncryptRuleInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+import org.mockito.internal.configuration.plugins.Plugins;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class EncryptRulesHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new EncryptRulesHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new EncryptRulesHandler().getResourceUriTemplate(), 
is(EncryptFeatureDefinition.RULES_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() throws ReflectiveOperationException {
+        EncryptRulesHandler handler = new EncryptRulesHandler();
+        EncryptRuleInspectionService ruleInspectionService = 
mock(EncryptRuleInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        when(ruleInspectionService.queryEncryptRules(queryFacade, 
"logic_db")).thenReturn(List.of(Map.of("logic_column", "phone")));
+        
Plugins.getMemberAccessor().set(EncryptRulesHandler.class.getDeclaredField("ruleInspectionService"),
 handler, ruleInspectionService);
+        MCPResponse actual = handler.handle(databaseContext, new 
MCPUriVariables(Map.of("database", "logic_db")));
+        verify(ruleInspectionService).queryEncryptRules(queryFacade, 
"logic_db");
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(1));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/encrypt/databases/logic_db/rules"));
+    }
+}
diff --git 
a/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/resource/handler/MaskAlgorithmsHandlerTest.java
 
b/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/resource/handler/MaskAlgorithmsHandlerTest.java
new file mode 100644
index 00000000000..a8ca0eee411
--- /dev/null
+++ 
b/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/resource/handler/MaskAlgorithmsHandlerTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.mcp.feature.mask.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import org.apache.shardingsphere.mcp.feature.mask.MaskFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.mask.tool.service.MaskRuleInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+import org.mockito.internal.configuration.plugins.Plugins;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class MaskAlgorithmsHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new MaskAlgorithmsHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new MaskAlgorithmsHandler().getResourceUriTemplate(), 
is(MaskFeatureDefinition.ALGORITHMS_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() throws ReflectiveOperationException {
+        MaskAlgorithmsHandler handler = new MaskAlgorithmsHandler();
+        MaskRuleInspectionService ruleInspectionService = 
mock(MaskRuleInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        
when(ruleInspectionService.queryMaskAlgorithms(queryFacade)).thenReturn(List.of(Map.of("type",
 "MD5")));
+        
Plugins.getMemberAccessor().set(MaskAlgorithmsHandler.class.getDeclaredField("ruleInspectionService"),
 handler, ruleInspectionService);
+        MCPResponse actual = handler.handle(databaseContext, new 
MCPUriVariables(Map.of()));
+        verify(ruleInspectionService).queryMaskAlgorithms(queryFacade);
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(1));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/mask/algorithms"));
+    }
+}
diff --git 
a/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/resource/handler/MaskResourceHandlerTest.java
 
b/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/resource/handler/MaskResourceHandlerTest.java
deleted file mode 100644
index 6ddb68bd266..00000000000
--- 
a/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/resource/handler/MaskResourceHandlerTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.mcp.feature.mask.resource.handler;
-
-import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
-import org.apache.shardingsphere.mcp.api.resource.MCPResourceHandler;
-import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
-import 
org.apache.shardingsphere.mcp.feature.mask.tool.service.MaskRuleInspectionService;
-import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
-import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
-import org.mockito.internal.configuration.plugins.Plugins;
-
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-class MaskResourceHandlerTest {
-    
-    @ParameterizedTest(name = "{0}")
-    @MethodSource("assertHandleArguments")
-    void assertHandle(final String name, final 
MCPResourceHandler<MCPDatabaseHandlerContext> handler, final Map<String, 
String> uriVariables,
-                      final String expectedDatabase, final String 
expectedTable, final List<Map<String, Object>> maskRules,
-                      final List<Map<String, Object>> maskAlgorithms, final 
String expectedSelfUri, final String expectedParentUri) throws 
ReflectiveOperationException {
-        MaskRuleInspectionService ruleInspectionService = 
mock(MaskRuleInspectionService.class);
-        Plugins.getMemberAccessor().set(((Object) 
handler).getClass().getDeclaredField("ruleInspectionService"), handler, 
ruleInspectionService);
-        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
-        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
-        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
-        when(ruleInspectionService.queryMaskRules(queryFacade, 
expectedDatabase)).thenReturn(maskRules);
-        when(ruleInspectionService.queryMaskRules(queryFacade, 
expectedDatabase, expectedTable)).thenReturn(maskRules);
-        
when(ruleInspectionService.queryMaskAlgorithms(queryFacade)).thenReturn(maskAlgorithms);
-        MCPResponse actual = handler.handle(databaseContext, new 
MCPUriVariables(uriVariables));
-        assertThat(((List<?>) actual.toPayload().get("items")).size(), is(1));
-        assertThat(actual.toPayload().get("self_uri"), is(expectedSelfUri));
-        if (expectedParentUri.isEmpty()) {
-            return;
-        }
-        assertThat(((Map<?, ?>) 
actual.toPayload().get("parent_resource")).get("uri"), is(expectedParentUri));
-    }
-    
-    private static Stream<Arguments> assertHandleArguments() {
-        return Stream.of(
-                Arguments.of("mask algorithms", new MaskAlgorithmsHandler(), 
Map.of(), "", "", List.of(), List.of(Map.of("type", "MD5")),
-                        "shardingsphere://features/mask/algorithms", ""),
-                Arguments.of("mask rules", new MaskRulesHandler(), 
Map.of("database", "logic_db"), "logic_db", "", List.of(Map.of("column", 
"phone")), List.of(),
-                        
"shardingsphere://features/mask/databases/logic_db/rules", ""),
-                Arguments.of("mask table rule", new MaskRuleHandler(), 
Map.of("database", "logic_db", "table", "orders"), "logic_db", "orders", 
List.of(Map.of("column", "phone")), List.of(),
-                        
"shardingsphere://features/mask/databases/logic_db/tables/orders/rules", 
"shardingsphere://features/mask/databases/logic_db/rules"));
-    }
-}
diff --git 
a/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/resource/handler/MaskRuleHandlerTest.java
 
b/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/resource/handler/MaskRuleHandlerTest.java
new file mode 100644
index 00000000000..7e75a83eee2
--- /dev/null
+++ 
b/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/resource/handler/MaskRuleHandlerTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.mcp.feature.mask.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import org.apache.shardingsphere.mcp.feature.mask.MaskFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.mask.tool.service.MaskRuleInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+import org.mockito.internal.configuration.plugins.Plugins;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class MaskRuleHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new MaskRuleHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new MaskRuleHandler().getResourceUriTemplate(), 
is(MaskFeatureDefinition.RULE_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() throws ReflectiveOperationException {
+        MaskRuleHandler handler = new MaskRuleHandler();
+        MaskRuleInspectionService ruleInspectionService = 
mock(MaskRuleInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        when(ruleInspectionService.queryMaskRules(queryFacade, "logic_db", 
"orders")).thenReturn(List.of(Map.of("column", "phone")));
+        
Plugins.getMemberAccessor().set(MaskRuleHandler.class.getDeclaredField("ruleInspectionService"),
 handler, ruleInspectionService);
+        MCPResponse actual = handler.handle(databaseContext, new 
MCPUriVariables(Map.of("database", "logic_db", "table", "orders")));
+        verify(ruleInspectionService).queryMaskRules(queryFacade, "logic_db", 
"orders");
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(1));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/mask/databases/logic_db/tables/orders/rules"));
+        assertThat(((Map<?, ?>) 
actual.toPayload().get("parent_resource")).get("uri"), 
is("shardingsphere://features/mask/databases/logic_db/rules"));
+    }
+}
diff --git 
a/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/resource/handler/MaskRulesHandlerTest.java
 
b/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/resource/handler/MaskRulesHandlerTest.java
new file mode 100644
index 00000000000..0f1a70c5ecb
--- /dev/null
+++ 
b/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/resource/handler/MaskRulesHandlerTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.mcp.feature.mask.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import org.apache.shardingsphere.mcp.feature.mask.MaskFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.mask.tool.service.MaskRuleInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+import org.mockito.internal.configuration.plugins.Plugins;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class MaskRulesHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new MaskRulesHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new MaskRulesHandler().getResourceUriTemplate(), 
is(MaskFeatureDefinition.RULES_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() throws ReflectiveOperationException {
+        MaskRulesHandler handler = new MaskRulesHandler();
+        MaskRuleInspectionService ruleInspectionService = 
mock(MaskRuleInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        when(ruleInspectionService.queryMaskRules(queryFacade, 
"logic_db")).thenReturn(List.of(Map.of("column", "phone")));
+        
Plugins.getMemberAccessor().set(MaskRulesHandler.class.getDeclaredField("ruleInspectionService"),
 handler, ruleInspectionService);
+        MCPResponse actual = handler.handle(databaseContext, new 
MCPUriVariables(Map.of("database", "logic_db")));
+        verify(ruleInspectionService).queryMaskRules(queryFacade, "logic_db");
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(1));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/mask/databases/logic_db/rules"));
+    }
+}
diff --git 
a/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/LoadBalanceAlgorithmPluginsHandlerTest.java
 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/LoadBalanceAlgorithmPluginsHandlerTest.java
new file mode 100644
index 00000000000..f54783a7597
--- /dev/null
+++ 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/LoadBalanceAlgorithmPluginsHandlerTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.mcp.feature.readwritesplitting.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import 
org.apache.shardingsphere.mcp.feature.readwritesplitting.ReadwriteSplittingFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.readwritesplitting.tool.service.ReadwriteSplittingInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class LoadBalanceAlgorithmPluginsHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new LoadBalanceAlgorithmPluginsHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new 
LoadBalanceAlgorithmPluginsHandler().getResourceUriTemplate(), 
is(ReadwriteSplittingFeatureDefinition.LOAD_BALANCE_ALGORITHM_PLUGINS_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() {
+        ReadwriteSplittingInspectionService inspectionService = 
mock(ReadwriteSplittingInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        
when(inspectionService.queryLoadBalanceAlgorithmPlugins(queryFacade)).thenReturn(List.of(Map.of("type",
 "ROUND_ROBIN")));
+        MCPResponse actual = new 
LoadBalanceAlgorithmPluginsHandler(inspectionService).handle(databaseContext, 
new MCPUriVariables(Map.of()));
+        
verify(inspectionService).queryLoadBalanceAlgorithmPlugins(queryFacade);
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(1));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/readwrite-splitting/load-balance-algorithm-plugins"));
+    }
+}
diff --git 
a/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingResourceHandlerTest.java
 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingResourceHandlerTest.java
deleted file mode 100644
index 78b7d3aceca..00000000000
--- 
a/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingResourceHandlerTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.mcp.feature.readwritesplitting.resource.handler;
-
-import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
-import org.apache.shardingsphere.mcp.api.resource.MCPResourceHandler;
-import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
-import 
org.apache.shardingsphere.mcp.feature.readwritesplitting.tool.service.ReadwriteSplittingInspectionService;
-import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
-import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
-
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-class ReadwriteSplittingResourceHandlerTest {
-    
-    @ParameterizedTest(name = "{0}")
-    @MethodSource("assertHandleArguments")
-    void assertHandle(final String name, final 
MCPResourceHandler<MCPDatabaseHandlerContext> handler, final MCPUriVariables 
uriVariables,
-                      final List<Map<String, Object>> rows, final String 
expectedSelfUri, final String expectedParentUri) {
-        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
-        
when(databaseContext.getQueryFacade()).thenReturn(mock(MCPFeatureQueryFacade.class));
-        MCPResponse actual = handler.handle(databaseContext, uriVariables);
-        assertThat(((List<?>) actual.toPayload().get("items")).size(), 
is(rows.size()));
-        assertThat(actual.toPayload().get("self_uri"), is(expectedSelfUri));
-        if (!expectedParentUri.isEmpty()) {
-            assertThat(((Map<?, ?>) 
actual.toPayload().get("parent_resource")).get("uri"), is(expectedParentUri));
-        }
-    }
-    
-    private static Stream<Arguments> assertHandleArguments() {
-        List<Map<String, Object>> rules = List.of(Map.of("name", 
"readwrite_ds"));
-        List<Map<String, Object>> statuses = List.of(Map.of("name", 
"readwrite_ds", "storage_unit", "read_ds_0", "status", "ENABLED"));
-        List<Map<String, Object>> count = List.of(Map.of("rule_name", 
"readwrite_splitting", "count", 1));
-        List<Map<String, Object>> plugins = List.of(Map.of("type", "RANDOM"));
-        ReadwriteSplittingInspectionService service = 
mock(ReadwriteSplittingInspectionService.class);
-        when(service.queryRules(any(), eq("logic_db"))).thenReturn(rules);
-        when(service.queryRule(any(), eq("logic_db"), 
eq("readwrite_ds"))).thenReturn(rules);
-        when(service.queryStatuses(any(), 
eq("logic_db"))).thenReturn(statuses);
-        when(service.queryRuleStatus(any(), eq("logic_db"), 
eq("readwrite_ds"))).thenReturn(statuses);
-        when(service.queryRuleCount(any(), eq("logic_db"))).thenReturn(count);
-        
when(service.queryLoadBalanceAlgorithmPlugins(any())).thenReturn(plugins);
-        return Stream.of(
-                Arguments.of("rules", new 
ReadwriteSplittingRulesHandler(service), new MCPUriVariables(Map.of("database", 
"logic_db")), rules,
-                        
"shardingsphere://features/readwrite-splitting/databases/logic_db/rules", ""),
-                Arguments.of("single rule", new 
ReadwriteSplittingRuleHandler(service), new MCPUriVariables(Map.of("database", 
"logic_db", "rule", "readwrite_ds")), rules,
-                        
"shardingsphere://features/readwrite-splitting/databases/logic_db/rules/readwrite_ds",
-                        
"shardingsphere://features/readwrite-splitting/databases/logic_db/rules"),
-                Arguments.of("status", new 
ReadwriteSplittingStatusHandler(service), new 
MCPUriVariables(Map.of("database", "logic_db")), statuses,
-                        
"shardingsphere://features/readwrite-splitting/databases/logic_db/status",
-                        
"shardingsphere://features/readwrite-splitting/databases/logic_db/rules"),
-                Arguments.of("rule status", new 
ReadwriteSplittingRuleStatusHandler(service), new 
MCPUriVariables(Map.of("database", "logic_db", "rule", "readwrite_ds")), 
statuses,
-                        
"shardingsphere://features/readwrite-splitting/databases/logic_db/rules/readwrite_ds/status",
-                        
"shardingsphere://features/readwrite-splitting/databases/logic_db/status"),
-                Arguments.of("rule count", new 
ReadwriteSplittingRuleCountHandler(service), new 
MCPUriVariables(Map.of("database", "logic_db")), count,
-                        
"shardingsphere://features/readwrite-splitting/databases/logic_db/rule-count",
-                        
"shardingsphere://features/readwrite-splitting/databases/logic_db/rules"),
-                Arguments.of("plugins", new 
LoadBalanceAlgorithmPluginsHandler(service), new MCPUriVariables(Map.of()), 
plugins,
-                        
"shardingsphere://features/readwrite-splitting/load-balance-algorithm-plugins", 
""));
-    }
-}
diff --git 
a/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingRuleCountHandlerTest.java
 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingRuleCountHandlerTest.java
new file mode 100644
index 00000000000..7896244b708
--- /dev/null
+++ 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingRuleCountHandlerTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.mcp.feature.readwritesplitting.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import 
org.apache.shardingsphere.mcp.feature.readwritesplitting.ReadwriteSplittingFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.readwritesplitting.tool.service.ReadwriteSplittingInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class ReadwriteSplittingRuleCountHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new ReadwriteSplittingRuleCountHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new 
ReadwriteSplittingRuleCountHandler().getResourceUriTemplate(), 
is(ReadwriteSplittingFeatureDefinition.RULE_COUNT_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() {
+        ReadwriteSplittingInspectionService inspectionService = 
mock(ReadwriteSplittingInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        when(inspectionService.queryRuleCount(queryFacade, 
"logic_db")).thenReturn(List.of(Map.of("rule_count", 1)));
+        MCPResponse actual = new 
ReadwriteSplittingRuleCountHandler(inspectionService).handle(databaseContext, 
new MCPUriVariables(Map.of("database", "logic_db")));
+        verify(inspectionService).queryRuleCount(queryFacade, "logic_db");
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(1));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/readwrite-splitting/databases/logic_db/rule-count"));
+        assertThat(((Map<?, ?>) 
actual.toPayload().get("parent_resource")).get("uri"), 
is("shardingsphere://features/readwrite-splitting/databases/logic_db/rules"));
+    }
+}
diff --git 
a/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingRuleHandlerTest.java
 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingRuleHandlerTest.java
new file mode 100644
index 00000000000..6d6e689368a
--- /dev/null
+++ 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingRuleHandlerTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.mcp.feature.readwritesplitting.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import 
org.apache.shardingsphere.mcp.feature.readwritesplitting.ReadwriteSplittingFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.readwritesplitting.tool.service.ReadwriteSplittingInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class ReadwriteSplittingRuleHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new ReadwriteSplittingRuleHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new 
ReadwriteSplittingRuleHandler().getResourceUriTemplate(), 
is(ReadwriteSplittingFeatureDefinition.RULE_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() {
+        ReadwriteSplittingInspectionService inspectionService = 
mock(ReadwriteSplittingInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        when(inspectionService.queryRule(queryFacade, "logic_db", 
"readwrite_ds")).thenReturn(List.of(Map.of("name", "readwrite_ds")));
+        MCPResponse actual = new 
ReadwriteSplittingRuleHandler(inspectionService).handle(databaseContext, new 
MCPUriVariables(Map.of("database", "logic_db", "rule", "readwrite_ds")));
+        verify(inspectionService).queryRule(queryFacade, "logic_db", 
"readwrite_ds");
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(1));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/readwrite-splitting/databases/logic_db/rules/readwrite_ds"));
+        assertThat(((Map<?, ?>) 
actual.toPayload().get("parent_resource")).get("uri"), 
is("shardingsphere://features/readwrite-splitting/databases/logic_db/rules"));
+    }
+}
diff --git 
a/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingRuleStatusHandlerTest.java
 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingRuleStatusHandlerTest.java
new file mode 100644
index 00000000000..cb9df977075
--- /dev/null
+++ 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingRuleStatusHandlerTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.mcp.feature.readwritesplitting.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import 
org.apache.shardingsphere.mcp.feature.readwritesplitting.ReadwriteSplittingFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.readwritesplitting.tool.service.ReadwriteSplittingInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class ReadwriteSplittingRuleStatusHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new ReadwriteSplittingRuleStatusHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new 
ReadwriteSplittingRuleStatusHandler().getResourceUriTemplate(), 
is(ReadwriteSplittingFeatureDefinition.RULE_STATUS_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() {
+        ReadwriteSplittingInspectionService inspectionService = 
mock(ReadwriteSplittingInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        when(inspectionService.queryRuleStatus(queryFacade, "logic_db", 
"readwrite_ds")).thenReturn(List.of(Map.of("storage_unit", "read_ds_0")));
+        MCPResponse actual = new 
ReadwriteSplittingRuleStatusHandler(inspectionService).handle(databaseContext, 
new MCPUriVariables(Map.of("database", "logic_db", "rule", "readwrite_ds")));
+        verify(inspectionService).queryRuleStatus(queryFacade, "logic_db", 
"readwrite_ds");
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(1));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/readwrite-splitting/databases/logic_db/rules/readwrite_ds/status"));
+        assertThat(((Map<?, ?>) 
actual.toPayload().get("parent_resource")).get("uri"), 
is("shardingsphere://features/readwrite-splitting/databases/logic_db/status"));
+    }
+}
diff --git 
a/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingRulesHandlerTest.java
 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingRulesHandlerTest.java
new file mode 100644
index 00000000000..aeede168ed3
--- /dev/null
+++ 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingRulesHandlerTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.mcp.feature.readwritesplitting.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import 
org.apache.shardingsphere.mcp.feature.readwritesplitting.ReadwriteSplittingFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.readwritesplitting.tool.service.ReadwriteSplittingInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class ReadwriteSplittingRulesHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new ReadwriteSplittingRulesHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new 
ReadwriteSplittingRulesHandler().getResourceUriTemplate(), 
is(ReadwriteSplittingFeatureDefinition.RULES_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() {
+        ReadwriteSplittingInspectionService inspectionService = 
mock(ReadwriteSplittingInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        when(inspectionService.queryRules(queryFacade, 
"logic_db")).thenReturn(List.of(Map.of("name", "readwrite_ds")));
+        MCPResponse actual = new 
ReadwriteSplittingRulesHandler(inspectionService).handle(databaseContext, new 
MCPUriVariables(Map.of("database", "logic_db")));
+        verify(inspectionService).queryRules(queryFacade, "logic_db");
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(1));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/readwrite-splitting/databases/logic_db/rules"));
+    }
+}
diff --git 
a/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingStatusHandlerTest.java
 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingStatusHandlerTest.java
new file mode 100644
index 00000000000..ad3b4d1beb7
--- /dev/null
+++ 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/resource/handler/ReadwriteSplittingStatusHandlerTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.mcp.feature.readwritesplitting.resource.handler;
+
+import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
+import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
+import 
org.apache.shardingsphere.mcp.feature.readwritesplitting.ReadwriteSplittingFeatureDefinition;
+import 
org.apache.shardingsphere.mcp.feature.readwritesplitting.tool.service.ReadwriteSplittingInspectionService;
+import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
+import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class ReadwriteSplittingStatusHandlerTest {
+    
+    @Test
+    void assertGetContextType() {
+        assertThat(new ReadwriteSplittingStatusHandler().getContextType(), 
is(MCPDatabaseHandlerContext.class));
+    }
+    
+    @Test
+    void assertGetResourceUriTemplate() {
+        assertThat(new 
ReadwriteSplittingStatusHandler().getResourceUriTemplate(), 
is(ReadwriteSplittingFeatureDefinition.STATUS_RESOURCE_URI));
+    }
+    
+    @Test
+    void assertHandle() {
+        ReadwriteSplittingInspectionService inspectionService = 
mock(ReadwriteSplittingInspectionService.class);
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
+        when(databaseContext.getQueryFacade()).thenReturn(queryFacade);
+        when(inspectionService.queryStatuses(queryFacade, 
"logic_db")).thenReturn(List.of(Map.of("storage_unit", "read_ds_0")));
+        MCPResponse actual = new 
ReadwriteSplittingStatusHandler(inspectionService).handle(databaseContext, new 
MCPUriVariables(Map.of("database", "logic_db")));
+        verify(inspectionService).queryStatuses(queryFacade, "logic_db");
+        assertThat(((Collection<?>) actual.toPayload().get("items")).size(), 
is(1));
+        assertThat(actual.toPayload().get("self_uri"), 
is("shardingsphere://features/readwrite-splitting/databases/logic_db/status"));
+        assertThat(((Map<?, ?>) 
actual.toPayload().get("parent_resource")).get("uri"), 
is("shardingsphere://features/readwrite-splitting/databases/logic_db/rules"));
+    }
+}
diff --git 
a/mcp/features/sharding/src/main/java/org/apache/shardingsphere/mcp/feature/sharding/resource/handler/ShardingResourceHandler.java
 
b/mcp/features/sharding/src/main/java/org/apache/shardingsphere/mcp/feature/sharding/resource/handler/ShardingResourceHandler.java
deleted file mode 100644
index 069b8856847..00000000000
--- 
a/mcp/features/sharding/src/main/java/org/apache/shardingsphere/mcp/feature/sharding/resource/handler/ShardingResourceHandler.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * 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.mcp.feature.sharding.resource.handler;
-
-import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
-import org.apache.shardingsphere.mcp.api.resource.MCPResourceHandler;
-import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
-import 
org.apache.shardingsphere.mcp.feature.sharding.ShardingFeatureDefinition;
-import 
org.apache.shardingsphere.mcp.feature.sharding.tool.service.ShardingInspectionService;
-import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
-import 
org.apache.shardingsphere.mcp.support.descriptor.MCPDescriptorCatalogIndex;
-import 
org.apache.shardingsphere.mcp.support.descriptor.MCPResourceNavigationPayloadBuilder;
-import 
org.apache.shardingsphere.mcp.support.protocol.response.MCPItemsResponse;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Sharding resource handler.
- */
-public final class ShardingResourceHandler implements 
MCPResourceHandler<MCPDatabaseHandlerContext> {
-    
-    private final String resourceUriTemplate;
-    
-    private final ResourceKind resourceKind;
-    
-    private final ShardingInspectionService inspectionService;
-    
-    private ShardingResourceHandler(final String resourceUriTemplate, final 
ResourceKind resourceKind) {
-        this(resourceUriTemplate, resourceKind, new 
ShardingInspectionService());
-    }
-    
-    ShardingResourceHandler(final String resourceUriTemplate, final 
ResourceKind resourceKind, final ShardingInspectionService inspectionService) {
-        this.resourceUriTemplate = resourceUriTemplate;
-        this.resourceKind = resourceKind;
-        this.inspectionService = inspectionService;
-    }
-    
-    /**
-     * Create handler for sharding algorithm plugin resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler algorithmPlugins() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.ALGORITHM_PLUGINS_RESOURCE_URI,
 ResourceKind.ALGORITHM_PLUGINS);
-    }
-    
-    /**
-     * Create handler for key generate algorithm plugin resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler keyGenerateAlgorithmPlugins() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.KEY_GENERATE_ALGORITHM_PLUGINS_RESOURCE_URI,
 ResourceKind.KEY_GENERATE_ALGORITHM_PLUGINS);
-    }
-    
-    /**
-     * Create handler for sharding algorithm resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler algorithms() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.ALGORITHMS_RESOURCE_URI, 
ResourceKind.ALGORITHMS);
-    }
-    
-    /**
-     * Create handler for sharding table rule resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler tableRules() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.TABLE_RULES_RESOURCE_URI, 
ResourceKind.TABLE_RULES);
-    }
-    
-    /**
-     * Create handler for a sharding table rule resource.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler tableRule() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.TABLE_RULE_RESOURCE_URI, 
ResourceKind.TABLE_RULE);
-    }
-    
-    /**
-     * Create handler for sharding table node resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler tableNodes() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.TABLE_NODES_RESOURCE_URI, 
ResourceKind.TABLE_NODES);
-    }
-    
-    /**
-     * Create handler for a sharding table node resource.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler tableNode() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.TABLE_NODE_RESOURCE_URI, 
ResourceKind.TABLE_NODE);
-    }
-    
-    /**
-     * Create handler for sharding table reference rule resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler tableReferenceRules() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.TABLE_REFERENCE_RULES_RESOURCE_URI,
 ResourceKind.TABLE_REFERENCE_RULES);
-    }
-    
-    /**
-     * Create handler for a sharding table reference rule resource.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler tableReferenceRule() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.TABLE_REFERENCE_RULE_RESOURCE_URI,
 ResourceKind.TABLE_REFERENCE_RULE);
-    }
-    
-    /**
-     * Create handler for default sharding strategy resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler defaultStrategy() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.DEFAULT_STRATEGY_RESOURCE_URI,
 ResourceKind.DEFAULT_STRATEGY);
-    }
-    
-    /**
-     * Create handler for sharding key generator resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler keyGenerators() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.KEY_GENERATORS_RESOURCE_URI, 
ResourceKind.KEY_GENERATORS);
-    }
-    
-    /**
-     * Create handler for a sharding key generator resource.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler keyGenerator() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.KEY_GENERATOR_RESOURCE_URI, 
ResourceKind.KEY_GENERATOR);
-    }
-    
-    /**
-     * Create handler for sharding key generate strategy resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler keyGenerateStrategies() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.KEY_GENERATE_STRATEGIES_RESOURCE_URI,
 ResourceKind.KEY_GENERATE_STRATEGIES);
-    }
-    
-    /**
-     * Create handler for a sharding key generate strategy resource.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler keyGenerateStrategy() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.KEY_GENERATE_STRATEGY_RESOURCE_URI,
 ResourceKind.KEY_GENERATE_STRATEGY);
-    }
-    
-    /**
-     * Create handler for sharding auditor resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler auditors() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.AUDITORS_RESOURCE_URI, 
ResourceKind.AUDITORS);
-    }
-    
-    /**
-     * Create handler for unused sharding algorithm resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler unusedAlgorithms() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.UNUSED_ALGORITHMS_RESOURCE_URI,
 ResourceKind.UNUSED_ALGORITHMS);
-    }
-    
-    /**
-     * Create handler for unused sharding key generator resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler unusedKeyGenerators() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.UNUSED_KEY_GENERATORS_RESOURCE_URI,
 ResourceKind.UNUSED_KEY_GENERATORS);
-    }
-    
-    /**
-     * Create handler for unused sharding auditor resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler unusedAuditors() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.UNUSED_AUDITORS_RESOURCE_URI, 
ResourceKind.UNUSED_AUDITORS);
-    }
-    
-    /**
-     * Create handler for table rules that use a sharding algorithm.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler algorithmUsedTableRules() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.ALGORITHM_USED_TABLE_RULES_RESOURCE_URI,
 ResourceKind.ALGORITHM_USED_TABLE_RULES);
-    }
-    
-    /**
-     * Create handler for table rules that use a sharding key generator.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler keyGeneratorUsedTableRules() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.KEY_GENERATOR_USED_TABLE_RULES_RESOURCE_URI,
 ResourceKind.KEY_GENERATOR_USED_TABLE_RULES);
-    }
-    
-    /**
-     * Create handler for table rules that use a sharding auditor.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler auditorUsedTableRules() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.AUDITOR_USED_TABLE_RULES_RESOURCE_URI,
 ResourceKind.AUDITOR_USED_TABLE_RULES);
-    }
-    
-    /**
-     * Create handler for sharding rule count resources.
-     *
-     * @return sharding resource handler
-     */
-    public static ShardingResourceHandler ruleCount() {
-        return new 
ShardingResourceHandler(ShardingFeatureDefinition.RULE_COUNT_RESOURCE_URI, 
ResourceKind.RULE_COUNT);
-    }
-    
-    @Override
-    public Class<MCPDatabaseHandlerContext> getContextType() {
-        return MCPDatabaseHandlerContext.class;
-    }
-    
-    @Override
-    public String getResourceUriTemplate() {
-        return resourceUriTemplate;
-    }
-    
-    @Override
-    public MCPResponse handle(final MCPDatabaseHandlerContext databaseContext, 
final MCPUriVariables uriVariables) {
-        return new MCPItemsResponse(query(databaseContext, uriVariables),
-                
MCPResourceNavigationPayloadBuilder.create(MCPDescriptorCatalogIndex.getRequiredResourceDescriptor(getResourceUriTemplate()),
 uriVariables));
-    }
-    
-    private List<Map<String, Object>> query(final MCPDatabaseHandlerContext 
databaseContext, final MCPUriVariables uriVariables) {
-        return switch (resourceKind) {
-            case ALGORITHM_PLUGINS -> 
inspectionService.queryAlgorithmPlugins(databaseContext.getQueryFacade());
-            case KEY_GENERATE_ALGORITHM_PLUGINS -> 
inspectionService.queryKeyGenerateAlgorithmPlugins(databaseContext.getQueryFacade());
-            default -> queryDatabaseScoped(databaseContext, uriVariables);
-        };
-    }
-    
-    private List<Map<String, Object>> queryDatabaseScoped(final 
MCPDatabaseHandlerContext databaseContext, final MCPUriVariables uriVariables) {
-        String databaseName = uriVariables.getValue("database");
-        return switch (resourceKind) {
-            case ALGORITHMS -> 
inspectionService.queryAlgorithms(databaseContext.getQueryFacade(), 
databaseName);
-            case TABLE_RULES -> 
inspectionService.queryTableRules(databaseContext.getQueryFacade(), 
databaseName);
-            case TABLE_RULE -> 
inspectionService.queryTableRule(databaseContext.getQueryFacade(), 
databaseName, uriVariables.getValue(ShardingFeatureDefinition.TABLE_FIELD));
-            case TABLE_NODES -> 
inspectionService.queryTableNodes(databaseContext.getQueryFacade(), 
databaseName);
-            case TABLE_NODE -> 
inspectionService.queryTableNode(databaseContext.getQueryFacade(), 
databaseName, uriVariables.getValue(ShardingFeatureDefinition.TABLE_FIELD));
-            case TABLE_REFERENCE_RULES -> 
inspectionService.queryTableReferenceRules(databaseContext.getQueryFacade(), 
databaseName);
-            case TABLE_REFERENCE_RULE -> 
inspectionService.queryTableReferenceRule(databaseContext.getQueryFacade(), 
databaseName, uriVariables.getValue(ShardingFeatureDefinition.RULE_FIELD));
-            case DEFAULT_STRATEGY -> 
inspectionService.queryDefaultStrategy(databaseContext.getQueryFacade(), 
databaseName);
-            case KEY_GENERATORS -> 
inspectionService.queryKeyGenerators(databaseContext.getQueryFacade(), 
databaseName);
-            case KEY_GENERATOR -> 
inspectionService.queryKeyGenerator(databaseContext.getQueryFacade(), 
databaseName, 
uriVariables.getValue(ShardingFeatureDefinition.KEY_GENERATOR_FIELD));
-            case KEY_GENERATE_STRATEGIES -> 
inspectionService.queryKeyGenerateStrategies(databaseContext.getQueryFacade(), 
databaseName);
-            case KEY_GENERATE_STRATEGY -> 
inspectionService.queryKeyGenerateStrategy(databaseContext.getQueryFacade(), 
databaseName, uriVariables.getValue(ShardingFeatureDefinition.STRATEGY_FIELD));
-            case AUDITORS -> 
inspectionService.queryAuditors(databaseContext.getQueryFacade(), databaseName);
-            case UNUSED_ALGORITHMS -> 
inspectionService.queryUnusedAlgorithms(databaseContext.getQueryFacade(), 
databaseName);
-            case UNUSED_KEY_GENERATORS -> 
inspectionService.queryUnusedKeyGenerators(databaseContext.getQueryFacade(), 
databaseName);
-            case UNUSED_AUDITORS -> 
inspectionService.queryUnusedAuditors(databaseContext.getQueryFacade(), 
databaseName);
-            case ALGORITHM_USED_TABLE_RULES -> 
inspectionService.queryTableRulesUsedAlgorithm(databaseContext.getQueryFacade(),
 databaseName,
-                    
uriVariables.getValue(ShardingFeatureDefinition.ALGORITHM_FIELD));
-            case KEY_GENERATOR_USED_TABLE_RULES -> 
inspectionService.queryTableRulesUsedKeyGenerator(databaseContext.getQueryFacade(),
 databaseName,
-                    
uriVariables.getValue(ShardingFeatureDefinition.KEY_GENERATOR_FIELD));
-            case AUDITOR_USED_TABLE_RULES -> 
inspectionService.queryTableRulesUsedAuditor(databaseContext.getQueryFacade(), 
databaseName,
-                    
uriVariables.getValue(ShardingFeatureDefinition.AUDITOR_FIELD));
-            case RULE_COUNT -> 
inspectionService.queryRuleCount(databaseContext.getQueryFacade(), 
databaseName);
-            default -> throw new IllegalStateException("Unsupported sharding 
resource kind.");
-        };
-    }
-    
-    enum ResourceKind {
-        
-        ALGORITHM_PLUGINS, KEY_GENERATE_ALGORITHM_PLUGINS, ALGORITHMS, 
TABLE_RULES, TABLE_RULE, TABLE_NODES, TABLE_NODE, TABLE_REFERENCE_RULES,
-        TABLE_REFERENCE_RULE, DEFAULT_STRATEGY, KEY_GENERATORS, KEY_GENERATOR, 
KEY_GENERATE_STRATEGIES, KEY_GENERATE_STRATEGY, AUDITORS, UNUSED_ALGORITHMS,
-        UNUSED_KEY_GENERATORS, UNUSED_AUDITORS, ALGORITHM_USED_TABLE_RULES, 
KEY_GENERATOR_USED_TABLE_RULES, AUDITOR_USED_TABLE_RULES, RULE_COUNT
-    }
-}
diff --git 
a/mcp/features/sharding/src/test/java/org/apache/shardingsphere/mcp/feature/sharding/resource/handler/ShardingResourceHandlerTest.java
 
b/mcp/features/sharding/src/test/java/org/apache/shardingsphere/mcp/feature/sharding/resource/handler/ShardingResourceHandlerTest.java
deleted file mode 100644
index 5ea4da8225b..00000000000
--- 
a/mcp/features/sharding/src/test/java/org/apache/shardingsphere/mcp/feature/sharding/resource/handler/ShardingResourceHandlerTest.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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.mcp.feature.sharding.resource.handler;
-
-import org.apache.shardingsphere.mcp.api.protocol.response.MCPResponse;
-import org.apache.shardingsphere.mcp.api.resource.MCPUriVariables;
-import 
org.apache.shardingsphere.mcp.feature.sharding.tool.service.ShardingInspectionService;
-import 
org.apache.shardingsphere.mcp.support.database.MCPDatabaseHandlerContext;
-import 
org.apache.shardingsphere.mcp.support.database.spi.MCPFeatureQueryFacade;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
-
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-class ShardingResourceHandlerTest {
-    
-    @ParameterizedTest(name = "{0}")
-    @MethodSource("assertHandleArguments")
-    void assertHandle(final String name, final ShardingResourceHandler 
handler, final MCPUriVariables uriVariables, final List<Map<String, Object>> 
rows, final String expectedSelfUri) {
-        MCPDatabaseHandlerContext databaseContext = 
mock(MCPDatabaseHandlerContext.class);
-        
when(databaseContext.getQueryFacade()).thenReturn(mock(MCPFeatureQueryFacade.class));
-        MCPResponse actual = handler.handle(databaseContext, uriVariables);
-        assertThat(((List<?>) actual.toPayload().get("items")).size(), 
is(rows.size()));
-        assertThat(actual.toPayload().get("self_uri"), is(expectedSelfUri));
-    }
-    
-    private static Stream<Arguments> assertHandleArguments() {
-        List<Map<String, Object>> rows = List.of(Map.of("name", 
"sharding_algorithm"));
-        ShardingInspectionService service = createInspectionService(rows);
-        return Stream.of(
-                createArguments("algorithm plugins", 
"shardingsphere://features/sharding/algorithm-plugins", 
ShardingResourceHandler.ResourceKind.ALGORITHM_PLUGINS,
-                        Map.of(), rows, 
"shardingsphere://features/sharding/algorithm-plugins", service),
-                createArguments("key generate algorithm plugins", 
"shardingsphere://features/sharding/key-generate-algorithm-plugins",
-                        
ShardingResourceHandler.ResourceKind.KEY_GENERATE_ALGORITHM_PLUGINS, Map.of(), 
rows,
-                        
"shardingsphere://features/sharding/key-generate-algorithm-plugins", service),
-                createArguments("algorithms", 
"shardingsphere://features/sharding/databases/{database}/algorithms",
-                        ShardingResourceHandler.ResourceKind.ALGORITHMS, 
Map.of("database", "logic_db"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/algorithms", service),
-                createArguments("table rules", 
"shardingsphere://features/sharding/databases/{database}/table-rules",
-                        ShardingResourceHandler.ResourceKind.TABLE_RULES, 
Map.of("database", "logic_db"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/table-rules", service),
-                createArguments("table rule", 
"shardingsphere://features/sharding/databases/{database}/tables/{table}/table-rule",
-                        ShardingResourceHandler.ResourceKind.TABLE_RULE, 
Map.of("database", "logic_db", "table", "t_order"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/tables/t_order/table-rule",
 service),
-                createArguments("table nodes", 
"shardingsphere://features/sharding/databases/{database}/table-nodes",
-                        ShardingResourceHandler.ResourceKind.TABLE_NODES, 
Map.of("database", "logic_db"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/table-nodes", service),
-                createArguments("table node", 
"shardingsphere://features/sharding/databases/{database}/tables/{table}/nodes",
-                        ShardingResourceHandler.ResourceKind.TABLE_NODE, 
Map.of("database", "logic_db", "table", "t_order"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/tables/t_order/nodes", 
service),
-                createArguments("table reference rules", 
"shardingsphere://features/sharding/databases/{database}/table-reference-rules",
-                        
ShardingResourceHandler.ResourceKind.TABLE_REFERENCE_RULES, Map.of("database", 
"logic_db"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/table-reference-rules", 
service),
-                createArguments("table reference rule", 
"shardingsphere://features/sharding/databases/{database}/table-reference-rules/{rule}",
-                        
ShardingResourceHandler.ResourceKind.TABLE_REFERENCE_RULE, Map.of("database", 
"logic_db", "rule", "ref_rule"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/table-reference-rules/ref_rule",
 service),
-                createArguments("default strategy", 
"shardingsphere://features/sharding/databases/{database}/default-strategy",
-                        ShardingResourceHandler.ResourceKind.DEFAULT_STRATEGY, 
Map.of("database", "logic_db"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/default-strategy", 
service),
-                createArguments("key generators", 
"shardingsphere://features/sharding/databases/{database}/key-generators",
-                        ShardingResourceHandler.ResourceKind.KEY_GENERATORS, 
Map.of("database", "logic_db"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/key-generators", 
service),
-                createArguments("key generator", 
"shardingsphere://features/sharding/databases/{database}/key-generators/{keyGenerator}",
-                        ShardingResourceHandler.ResourceKind.KEY_GENERATOR, 
Map.of("database", "logic_db", "keyGenerator", "snowflake_generator"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/key-generators/snowflake_generator",
 service),
-                createArguments("key generate strategies", 
"shardingsphere://features/sharding/databases/{database}/key-generate-strategies",
-                        
ShardingResourceHandler.ResourceKind.KEY_GENERATE_STRATEGIES, 
Map.of("database", "logic_db"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/key-generate-strategies",
 service),
-                createArguments("key generate strategy", 
"shardingsphere://features/sharding/databases/{database}/key-generate-strategies/{strategy}",
-                        
ShardingResourceHandler.ResourceKind.KEY_GENERATE_STRATEGY, Map.of("database", 
"logic_db", "strategy", "order_key_strategy"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/key-generate-strategies/order_key_strategy",
 service),
-                createArguments("auditors", 
"shardingsphere://features/sharding/databases/{database}/auditors",
-                        ShardingResourceHandler.ResourceKind.AUDITORS, 
Map.of("database", "logic_db"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/auditors", service),
-                createArguments("unused algorithms", 
"shardingsphere://features/sharding/databases/{database}/unused-algorithms",
-                        
ShardingResourceHandler.ResourceKind.UNUSED_ALGORITHMS, Map.of("database", 
"logic_db"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/unused-algorithms", 
service),
-                createArguments("unused key generators", 
"shardingsphere://features/sharding/databases/{database}/unused-key-generators",
-                        
ShardingResourceHandler.ResourceKind.UNUSED_KEY_GENERATORS, Map.of("database", 
"logic_db"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/unused-key-generators", 
service),
-                createArguments("unused auditors", 
"shardingsphere://features/sharding/databases/{database}/unused-auditors",
-                        ShardingResourceHandler.ResourceKind.UNUSED_AUDITORS, 
Map.of("database", "logic_db"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/unused-auditors", 
service),
-                createArguments("algorithm used table rules", 
"shardingsphere://features/sharding/databases/{database}/algorithms/{algorithm}/table-rules",
-                        
ShardingResourceHandler.ResourceKind.ALGORITHM_USED_TABLE_RULES, 
Map.of("database", "logic_db", "algorithm", "inline_algorithm"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/algorithms/inline_algorithm/table-rules",
 service),
-                createArguments("key generator used table rules", 
"shardingsphere://features/sharding/databases/{database}/key-generators/{keyGenerator}/table-rules",
-                        
ShardingResourceHandler.ResourceKind.KEY_GENERATOR_USED_TABLE_RULES, 
Map.of("database", "logic_db", "keyGenerator", "snowflake_generator"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/key-generators/snowflake_generator/table-rules",
 service),
-                createArguments("auditor used table rules", 
"shardingsphere://features/sharding/databases/{database}/auditors/{auditor}/table-rules",
-                        
ShardingResourceHandler.ResourceKind.AUDITOR_USED_TABLE_RULES, 
Map.of("database", "logic_db", "auditor", "dml_auditor"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/auditors/dml_auditor/table-rules",
 service),
-                createArguments("rule count", 
"shardingsphere://features/sharding/databases/{database}/rule-count",
-                        ShardingResourceHandler.ResourceKind.RULE_COUNT, 
Map.of("database", "logic_db"), rows,
-                        
"shardingsphere://features/sharding/databases/logic_db/rule-count", service));
-    }
-    
-    private static Arguments createArguments(final String name, final String 
resourceUriTemplate, final ShardingResourceHandler.ResourceKind resourceKind,
-                                             final Map<String, String> 
uriVariables, final List<Map<String, Object>> rows, final String 
expectedSelfUri,
-                                             final ShardingInspectionService 
service) {
-        return Arguments.of(name, new 
ShardingResourceHandler(resourceUriTemplate, resourceKind, service), new 
MCPUriVariables(uriVariables), rows, expectedSelfUri);
-    }
-    
-    private static ShardingInspectionService createInspectionService(final 
List<Map<String, Object>> rows) {
-        ShardingInspectionService result = 
mock(ShardingInspectionService.class);
-        when(result.queryAlgorithmPlugins(any())).thenReturn(rows);
-        when(result.queryKeyGenerateAlgorithmPlugins(any())).thenReturn(rows);
-        when(result.queryAlgorithms(any(), eq("logic_db"))).thenReturn(rows);
-        when(result.queryTableRules(any(), eq("logic_db"))).thenReturn(rows);
-        when(result.queryTableRule(any(), eq("logic_db"), 
eq("t_order"))).thenReturn(rows);
-        when(result.queryTableNodes(any(), eq("logic_db"))).thenReturn(rows);
-        when(result.queryTableNode(any(), eq("logic_db"), 
eq("t_order"))).thenReturn(rows);
-        when(result.queryTableReferenceRules(any(), 
eq("logic_db"))).thenReturn(rows);
-        when(result.queryTableReferenceRule(any(), eq("logic_db"), 
eq("ref_rule"))).thenReturn(rows);
-        when(result.queryDefaultStrategy(any(), 
eq("logic_db"))).thenReturn(rows);
-        when(result.queryKeyGenerators(any(), 
eq("logic_db"))).thenReturn(rows);
-        when(result.queryKeyGenerator(any(), eq("logic_db"), 
eq("snowflake_generator"))).thenReturn(rows);
-        when(result.queryKeyGenerateStrategies(any(), 
eq("logic_db"))).thenReturn(rows);
-        when(result.queryKeyGenerateStrategy(any(), eq("logic_db"), 
eq("order_key_strategy"))).thenReturn(rows);
-        when(result.queryAuditors(any(), eq("logic_db"))).thenReturn(rows);
-        when(result.queryUnusedAlgorithms(any(), 
eq("logic_db"))).thenReturn(rows);
-        when(result.queryUnusedKeyGenerators(any(), 
eq("logic_db"))).thenReturn(rows);
-        when(result.queryUnusedAuditors(any(), 
eq("logic_db"))).thenReturn(rows);
-        when(result.queryTableRulesUsedAlgorithm(any(), eq("logic_db"), 
eq("inline_algorithm"))).thenReturn(rows);
-        when(result.queryTableRulesUsedKeyGenerator(any(), eq("logic_db"), 
eq("snowflake_generator"))).thenReturn(rows);
-        when(result.queryTableRulesUsedAuditor(any(), eq("logic_db"), 
eq("dml_auditor"))).thenReturn(rows);
-        when(result.queryRuleCount(any(), eq("logic_db"))).thenReturn(rows);
-        return result;
-    }
-}

Reply via email to