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 bf9ea8826b6 Refactor MCP E2E support contracts (#39002)
bf9ea8826b6 is described below

commit bf9ea8826b62c45412b09c9f46e541a64f5448bd
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Jul 5 11:50:31 2026 +0800

    Refactor MCP E2E support contracts (#39002)
---
 .../llm/conversation/LLMMCPActionExecutorTest.java | 20 ++++++++++
 .../PackagedDistributionTestSupport.java           | 34 ++++++++++-------
 .../PackagedDistributionTestSupportTest.java       | 27 +++++++++++++-
 .../client/AbstractMCPInteractionClientTest.java   |  5 +++
 .../transport/client/MCPInteractionClient.java     | 43 +++++-----------------
 5 files changed, 79 insertions(+), 50 deletions(-)

diff --git 
a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/conversation/LLMMCPActionExecutorTest.java
 
b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/conversation/LLMMCPActionExecutorTest.java
index 894ec83049d..d5269b67e27 100644
--- 
a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/conversation/LLMMCPActionExecutorTest.java
+++ 
b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/conversation/LLMMCPActionExecutorTest.java
@@ -173,6 +173,16 @@ class LLMMCPActionExecutorTest {
             return Map.of("result_kind", "result_set");
         }
         
+        @Override
+        public Map<String, Object> getInitializePayload() {
+            throw new UnsupportedOperationException("initialize payload is not 
available.");
+        }
+        
+        @Override
+        public List<Map<String, Object>> listTools() {
+            throw new UnsupportedOperationException("tools/list is not 
supported.");
+        }
+        
         @Override
         public Map<String, Object> listResources() throws IOException {
             if (failWithIOException) {
@@ -181,6 +191,11 @@ class LLMMCPActionExecutorTest {
             return Map.of("resources", List.of());
         }
         
+        @Override
+        public Map<String, Object> listResourceTemplates() {
+            throw new UnsupportedOperationException("resources/templates/list 
is not supported.");
+        }
+        
         @Override
         public Map<String, Object> readResource(final String resourceUri) {
             this.resourceUri = resourceUri;
@@ -208,6 +223,11 @@ class LLMMCPActionExecutorTest {
             return Map.of("completion", "public");
         }
         
+        @Override
+        public Map<String, Object> sendRawRequest(final String requestId, 
final String method, final Map<String, Object> params) {
+            throw new UnsupportedOperationException("Raw JSON-RPC request is 
not supported.");
+        }
+        
         @Override
         public void close() {
         }
diff --git 
a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/distribution/PackagedDistributionTestSupport.java
 
b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/distribution/PackagedDistributionTestSupport.java
index 95343e05c36..2d401f3289e 100644
--- 
a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/distribution/PackagedDistributionTestSupport.java
+++ 
b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/distribution/PackagedDistributionTestSupport.java
@@ -84,9 +84,7 @@ public final class PackagedDistributionTestSupport {
     public static PreparedPackagedDistribution prepare(final Path tempDir, 
final RuntimeTransport transport,
                                                        final Map<String, 
RuntimeDatabaseConfiguration> runtimeDatabases) throws IOException {
         Path workingHome = prepareWorkingHome(tempDir);
-        int httpPort = resolveHttpPort(transport);
-        Path configFile = rewriteConfiguration(workingHome, transport, 
httpPort, runtimeDatabases);
-        return new PreparedPackagedDistribution(workingHome, configFile, 
transport, httpPort);
+        return createPreparedDistribution(workingHome, transport, 
runtimeDatabases);
     }
     
     /**
@@ -101,9 +99,14 @@ public final class PackagedDistributionTestSupport {
     public static PreparedPackagedDistribution prepareReusable(final Path 
workingHome, final RuntimeTransport transport,
                                                                final 
Map<String, RuntimeDatabaseConfiguration> runtimeDatabases) throws IOException {
         Path actualWorkingHome = prepareReusableWorkingHome(workingHome);
+        return createPreparedDistribution(actualWorkingHome, transport, 
runtimeDatabases);
+    }
+    
+    private static PreparedPackagedDistribution 
createPreparedDistribution(final Path workingHome, final RuntimeTransport 
transport,
+                                                                           
final Map<String, RuntimeDatabaseConfiguration> runtimeDatabases) throws 
IOException {
         int httpPort = resolveHttpPort(transport);
-        Path configFile = rewriteConfiguration(actualWorkingHome, transport, 
httpPort, runtimeDatabases);
-        return new PreparedPackagedDistribution(actualWorkingHome, configFile, 
transport, httpPort);
+        Path configFile = rewriteConfiguration(workingHome, transport, 
httpPort, runtimeDatabases);
+        return new PreparedPackagedDistribution(workingHome, configFile, 
transport, httpPort);
     }
     
     /**
@@ -117,10 +120,12 @@ public final class PackagedDistributionTestSupport {
      */
     public static Path createDockerConfigurationFile(final Path targetFile, 
final RuntimeTransport transport,
                                                      final Map<String, 
RuntimeDatabaseConfiguration> runtimeDatabases) throws IOException {
-        HttpTransportConfiguration httpTransport = new 
HttpTransportConfiguration(DOCKER_BIND_HOST, DOCKER_HTTP_PORT, 
DEFAULT_ENDPOINT_PATH);
-        MCPTransportType transportType = RuntimeTransport.HTTP == transport ? 
MCPTransportType.STREAMABLE_HTTP : MCPTransportType.STDIO;
-        Files.writeString(targetFile, YamlEngine.marshal(new 
YamlMCPLaunchConfigurationSwapper().swapToYamlConfiguration(
-                new MCPLaunchConfiguration(transportType, httpTransport, 
runtimeDatabases))));
+        return writeConfiguration(targetFile, new 
MCPLaunchConfiguration(resolveTransportType(transport),
+                new HttpTransportConfiguration(DOCKER_BIND_HOST, 
DOCKER_HTTP_PORT, DEFAULT_ENDPOINT_PATH), runtimeDatabases));
+    }
+    
+    private static Path writeConfiguration(final Path targetFile, final 
MCPLaunchConfiguration config) throws IOException {
+        Files.writeString(targetFile, YamlEngine.marshal(new 
YamlMCPLaunchConfigurationSwapper().swapToYamlConfiguration(config)));
         return targetFile;
     }
     
@@ -270,9 +275,7 @@ public final class PackagedDistributionTestSupport {
                                              final Map<String, 
RuntimeDatabaseConfiguration> runtimeDatabases) throws IOException {
         Path result = resolveConfigFile(workingHome, transport);
         MCPLaunchConfiguration sourceConfig = 
MCPConfigurationLoader.load(result.toString());
-        MCPLaunchConfiguration actualConfig = 
createRuntimeConfiguration(sourceConfig, transport, httpPort, runtimeDatabases);
-        Files.writeString(result, YamlEngine.marshal(new 
YamlMCPLaunchConfigurationSwapper().swapToYamlConfiguration(actualConfig)));
-        return result;
+        return writeConfiguration(result, 
createRuntimeConfiguration(sourceConfig, transport, httpPort, 
runtimeDatabases));
     }
     
     private static Path resolveConfigFile(final Path workingHome, final 
RuntimeTransport transport) {
@@ -283,8 +286,11 @@ public final class PackagedDistributionTestSupport {
                                                                      final int 
httpPort, final Map<String, RuntimeDatabaseConfiguration> runtimeDatabases) {
         HttpTransportConfiguration actualHttpTransport = new 
HttpTransportConfiguration(sourceConfig.getHttpTransport().getBindHost(),
                 RuntimeTransport.HTTP == transport ? httpPort : 
sourceConfig.getHttpTransport().getPort(), 
sourceConfig.getHttpTransport().getEndpointPath());
-        MCPTransportType transportType = RuntimeTransport.HTTP == transport ? 
MCPTransportType.STREAMABLE_HTTP : MCPTransportType.STDIO;
-        return new MCPLaunchConfiguration(transportType, actualHttpTransport, 
runtimeDatabases.isEmpty() ? sourceConfig.getDatabases() : runtimeDatabases);
+        return new MCPLaunchConfiguration(resolveTransportType(transport), 
actualHttpTransport, runtimeDatabases.isEmpty() ? sourceConfig.getDatabases() : 
runtimeDatabases);
+    }
+    
+    private static MCPTransportType resolveTransportType(final 
RuntimeTransport transport) {
+        return RuntimeTransport.HTTP == transport ? 
MCPTransportType.STREAMABLE_HTTP : MCPTransportType.STDIO;
     }
     
     public record PreparedPackagedDistribution(Path home, Path configFile, 
RuntimeTransport transport, int httpPort) {
diff --git 
a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/distribution/PackagedDistributionTestSupportTest.java
 
b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/distribution/PackagedDistributionTestSupportTest.java
index 0b56ca6ae01..4b52f715939 100644
--- 
a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/distribution/PackagedDistributionTestSupportTest.java
+++ 
b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/distribution/PackagedDistributionTestSupportTest.java
@@ -23,6 +23,7 @@ import static org.hamcrest.Matchers.is;
 import org.apache.shardingsphere.mcp.bootstrap.config.MCPLaunchConfiguration;
 import org.apache.shardingsphere.mcp.bootstrap.config.MCPTransportType;
 import 
org.apache.shardingsphere.mcp.bootstrap.config.loader.MCPConfigurationLoader;
+import 
org.apache.shardingsphere.mcp.support.database.metadata.jdbc.RuntimeDatabaseConfiguration;
 import 
org.apache.shardingsphere.test.e2e.mcp.support.distribution.PackagedDistributionTestSupport.PreparedPackagedDistribution;
 import org.apache.shardingsphere.test.e2e.mcp.support.runtime.RuntimeTransport;
 import org.junit.jupiter.api.Test;
@@ -34,6 +35,7 @@ import org.junit.jupiter.params.provider.MethodSource;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Stream;
 
@@ -131,7 +133,7 @@ class PackagedDistributionTestSupportTest {
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("prepareCases")
+    @MethodSource("transportCases")
     void assertPrepareWithTransport(final String caseName, final 
RuntimeTransport transport, final MCPTransportType expectedTransportType) 
throws IOException {
         Path distributionHome = 
createDistributionHome(tempDir.resolve(caseName));
         String actualOriginalHome = 
System.getProperty("mcp.distribution.home");
@@ -161,7 +163,28 @@ class PackagedDistributionTestSupportTest {
         }
     }
     
-    private static Stream<Arguments> prepareCases() {
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("transportCases")
+    void assertCreateDockerConfigurationFile(final String caseName, final 
RuntimeTransport transport, final MCPTransportType expectedTransportType) 
throws IOException {
+        Path targetFile = tempDir.resolve(caseName + ".yaml");
+        RuntimeDatabaseConfiguration expectedRuntimeDatabase = new 
RuntimeDatabaseConfiguration("jdbc:mysql://127.0.0.1:3306/orders", "mcp", 
"mcp", "com.mysql.cj.jdbc.Driver");
+        Path actual = 
PackagedDistributionTestSupport.createDockerConfigurationFile(targetFile, 
transport, Map.of("logic_db", expectedRuntimeDatabase));
+        assertThat(actual, is(targetFile));
+        MCPLaunchConfiguration actualConfig = 
MCPConfigurationLoader.load(actual.toString());
+        assertThat(actualConfig.getTransportType(), is(expectedTransportType));
+        if (RuntimeTransport.HTTP == transport) {
+            assertThat(actualConfig.getHttpTransport().getBindHost(), 
is("0.0.0.0"));
+            assertThat(actualConfig.getHttpTransport().getPort(), is(18088));
+            assertThat(actualConfig.getHttpTransport().getEndpointPath(), 
is("/mcp"));
+        }
+        RuntimeDatabaseConfiguration actualRuntimeDatabase = 
actualConfig.getDatabases().get("logic_db");
+        assertThat(actualRuntimeDatabase.getJdbcUrl(), 
is(expectedRuntimeDatabase.getJdbcUrl()));
+        assertThat(actualRuntimeDatabase.getUsername(), 
is(expectedRuntimeDatabase.getUsername()));
+        assertThat(actualRuntimeDatabase.getPassword(), 
is(expectedRuntimeDatabase.getPassword()));
+        assertThat(actualRuntimeDatabase.getDriverClassName(), 
is(expectedRuntimeDatabase.getDriverClassName()));
+    }
+    
+    private static Stream<Arguments> transportCases() {
         return Stream.of(
                 Arguments.of("http transport", RuntimeTransport.HTTP, 
MCPTransportType.STREAMABLE_HTTP),
                 Arguments.of("stdio transport", RuntimeTransport.STDIO, 
MCPTransportType.STDIO));
diff --git 
a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/transport/client/AbstractMCPInteractionClientTest.java
 
b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/transport/client/AbstractMCPInteractionClientTest.java
index 3265fbddf7d..df872604230 100644
--- 
a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/transport/client/AbstractMCPInteractionClientTest.java
+++ 
b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/transport/client/AbstractMCPInteractionClientTest.java
@@ -139,6 +139,11 @@ class AbstractMCPInteractionClientTest {
         public void open() {
         }
         
+        @Override
+        public Map<String, Object> getInitializePayload() {
+            throw new UnsupportedOperationException("initialize payload is not 
available.");
+        }
+        
         @Override
         public void close() {
         }
diff --git 
a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/transport/client/MCPInteractionClient.java
 
b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/transport/client/MCPInteractionClient.java
index 8b92d52ba56..f82978e4d44 100644
--- 
a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/transport/client/MCPInteractionClient.java
+++ 
b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/support/transport/client/MCPInteractionClient.java
@@ -49,11 +49,8 @@ public interface MCPInteractionClient extends AutoCloseable {
      * Get initialize payload.
      *
      * @return raw initialize JSON-RPC payload
-     * @throws UnsupportedOperationException unsupported operation exception
      */
-    default Map<String, Object> getInitializePayload() {
-        throw new UnsupportedOperationException("initialize payload is not 
available.");
-    }
+    Map<String, Object> getInitializePayload();
     
     /**
      * List tools.
@@ -61,11 +58,8 @@ public interface MCPInteractionClient extends AutoCloseable {
      * @return MCP tool list payload
      * @throws IOException IO exception
      * @throws InterruptedException interrupted exception
-     * @throws UnsupportedOperationException unsupported operation exception
      */
-    default List<Map<String, Object>> listTools() throws IOException, 
InterruptedException {
-        throw new UnsupportedOperationException("tools/list is not 
supported.");
-    }
+    List<Map<String, Object>> listTools() throws IOException, 
InterruptedException;
     
     /**
      * List resources.
@@ -73,11 +67,8 @@ public interface MCPInteractionClient extends AutoCloseable {
      * @return MCP resources payload
      * @throws IOException IO exception
      * @throws InterruptedException interrupted exception
-     * @throws UnsupportedOperationException unsupported operation exception
      */
-    default Map<String, Object> listResources() throws IOException, 
InterruptedException {
-        throw new UnsupportedOperationException("resources/list is not 
supported.");
-    }
+    Map<String, Object> listResources() throws IOException, 
InterruptedException;
     
     /**
      * List resource templates.
@@ -85,11 +76,8 @@ public interface MCPInteractionClient extends AutoCloseable {
      * @return MCP resource templates payload
      * @throws IOException IO exception
      * @throws InterruptedException interrupted exception
-     * @throws UnsupportedOperationException unsupported operation exception
      */
-    default Map<String, Object> listResourceTemplates() throws IOException, 
InterruptedException {
-        throw new UnsupportedOperationException("resources/templates/list is 
not supported.");
-    }
+    Map<String, Object> listResourceTemplates() throws IOException, 
InterruptedException;
     
     /**
      * List prompts.
@@ -97,11 +85,8 @@ public interface MCPInteractionClient extends AutoCloseable {
      * @return MCP prompts payload
      * @throws IOException IO exception
      * @throws InterruptedException interrupted exception
-     * @throws UnsupportedOperationException unsupported operation exception
      */
-    default Map<String, Object> listPrompts() throws IOException, 
InterruptedException {
-        throw new UnsupportedOperationException("prompts/list is not 
supported.");
-    }
+    Map<String, Object> listPrompts() throws IOException, InterruptedException;
     
     /**
      * Get prompt.
@@ -111,11 +96,8 @@ public interface MCPInteractionClient extends AutoCloseable 
{
      * @return MCP prompt payload
      * @throws IOException IO exception
      * @throws InterruptedException interrupted exception
-     * @throws UnsupportedOperationException unsupported operation exception
      */
-    default Map<String, Object> getPrompt(final String promptName, final 
Map<String, Object> arguments) throws IOException, InterruptedException {
-        throw new UnsupportedOperationException("prompts/get is not 
supported.");
-    }
+    Map<String, Object> getPrompt(String promptName, Map<String, Object> 
arguments) throws IOException, InterruptedException;
     
     /**
      * Complete one argument.
@@ -127,12 +109,9 @@ public interface MCPInteractionClient extends 
AutoCloseable {
      * @return MCP completion payload
      * @throws IOException IO exception
      * @throws InterruptedException interrupted exception
-     * @throws UnsupportedOperationException unsupported operation exception
      */
-    default Map<String, Object> complete(final Map<String, Object> reference, 
final String argumentName, final String argumentValue,
-                                         final Map<String, String> 
contextArguments) throws IOException, InterruptedException {
-        throw new UnsupportedOperationException("completion/complete is not 
supported.");
-    }
+    Map<String, Object> complete(Map<String, Object> reference, String 
argumentName, String argumentValue,
+                                 Map<String, String> contextArguments) throws 
IOException, InterruptedException;
     
     /**
      * Read resource.
@@ -141,7 +120,6 @@ public interface MCPInteractionClient extends AutoCloseable 
{
      * @return MCP resource payload
      * @throws IOException IO exception
      * @throws InterruptedException interrupted exception
-     * @throws UnsupportedOperationException unsupported operation exception
      */
     Map<String, Object> readResource(String resourceUri) throws IOException, 
InterruptedException;
     
@@ -154,11 +132,8 @@ public interface MCPInteractionClient extends 
AutoCloseable {
      * @return raw JSON-RPC payload
      * @throws IOException IO exception
      * @throws InterruptedException interrupted exception
-     * @throws UnsupportedOperationException unsupported operation exception
      */
-    default Map<String, Object> sendRawRequest(final String requestId, final 
String method, final Map<String, Object> params) throws IOException, 
InterruptedException {
-        throw new UnsupportedOperationException("Raw JSON-RPC request is not 
supported.");
-    }
+    Map<String, Object> sendRawRequest(String requestId, String method, 
Map<String, Object> params) throws IOException, InterruptedException;
     
     @Override
     void close() throws IOException, InterruptedException;

Reply via email to