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;