This is an automated email from the ASF dual-hosted git repository.
wy471x pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new bc41eb74d6 fix(mcp): close the previous server when a selector path
changes (#7493)
bc41eb74d6 is described below
commit bc41eb74d68ea7a529f139ef46740ba4c10d6792
Author: Sean-Walker0 <[email protected]>
AuthorDate: Sat Oct 10 21:59:30 2026 +0800
fix(mcp): close the previous server when a selector path changes (#7493)
handlerSelector() overwrote the cached server handle and created the
transports for the new path, but the server registered under the
previous path was never removed. After an MCP selector update from
/mcp/old/** to /mcp/new/**, the old path's server, routes and
transports stayed alive, and the old endpoint kept serving sessions.
Before replacing the cached handle, look up the previous server and,
when its path differs from the new one, close its MCP server via the
existing removeMcpServer path. Regression test updates a selector
from /mcp/old/** to /mcp/new/** and asserts the old server is removed
(red on the previous code, which never removed it).
Fixes #7472
Co-authored-by: Sean-Walker0
<[email protected]>
---
.../server/handler/McpServerPluginDataHandler.java | 7 +++++++
.../handler/McpServerPluginDataHandlerTest.java | 22 ++++++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git
a/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/handler/McpServerPluginDataHandler.java
b/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/handler/McpServerPluginDataHandler.java
index b083dd21d6..e22d92861b 100644
---
a/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/handler/McpServerPluginDataHandler.java
+++
b/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/handler/McpServerPluginDataHandler.java
@@ -88,6 +88,13 @@ public class McpServerPluginDataHandler implements
PluginDataHandler {
}
ShenyuMcpServer shenyuMcpServer =
GsonUtils.getInstance().fromJson(StringUtils.isBlank(selectorData.getHandle())
? DEFAULT_MESSAGE_ENDPOINT : selectorData.getHandle(), ShenyuMcpServer.class);
shenyuMcpServer.setPath(path);
+ // when the selector moves to another path, close the server
registered for the old
+ // one, otherwise its routes and transports stay alive under the
previous endpoint
+ ShenyuMcpServer previousServer =
CACHED_SERVER.get().obtainHandle(selectorData.getId());
+ if (Objects.nonNull(previousServer) &&
StringUtils.isNotBlank(previousServer.getPath())
+ && !previousServer.getPath().equals(path) &&
shenyuMcpServerManager.hasMcpServer(previousServer.getPath())) {
+ shenyuMcpServerManager.removeMcpServer(previousServer.getPath());
+ }
CACHED_SERVER.get().cachedHandle(
selectorData.getId(),
shenyuMcpServer);
diff --git
a/shenyu-plugin/shenyu-plugin-mcp-server/src/test/java/org/apache/shenyu/plugin/mcp/server/handler/McpServerPluginDataHandlerTest.java
b/shenyu-plugin/shenyu-plugin-mcp-server/src/test/java/org/apache/shenyu/plugin/mcp/server/handler/McpServerPluginDataHandlerTest.java
index 7d44fa9052..64b2beb721 100644
---
a/shenyu-plugin/shenyu-plugin-mcp-server/src/test/java/org/apache/shenyu/plugin/mcp/server/handler/McpServerPluginDataHandlerTest.java
+++
b/shenyu-plugin/shenyu-plugin-mcp-server/src/test/java/org/apache/shenyu/plugin/mcp/server/handler/McpServerPluginDataHandlerTest.java
@@ -157,6 +157,28 @@ class McpServerPluginDataHandlerTest {
verify(shenyuMcpServerManager).removeMcpServer(eq("/mcp/test"));
}
+ @Test
+ void testHandlerSelectorPathUpdateRemovesPreviousServer() {
+ org.apache.shenyu.plugin.mcp.server.model.ShenyuMcpServer
previousServer =
+ new
org.apache.shenyu.plugin.mcp.server.model.ShenyuMcpServer();
+ previousServer.setPath("/mcp/old");
+
McpServerPluginDataHandler.CACHED_SERVER.get().cachedHandle("selector1",
previousServer);
+
when(shenyuMcpServerManager.hasMcpServer(anyString())).thenReturn(false);
+ when(shenyuMcpServerManager.hasMcpServer("/mcp/old")).thenReturn(true);
+
+ ConditionData condition = new ConditionData();
+ condition.setParamType(ParamTypeEnum.URI.getName());
+ condition.setParamValue("/mcp/new/**");
+ SelectorData selectorData = new SelectorData();
+ selectorData.setId("selector1");
+ selectorData.setConditionList(Arrays.asList(condition));
+ selectorData.setHandle("{\"messageEndpoint\":\"/message\"}");
+
+ dataHandler.handlerSelector(selectorData);
+
+ verify(shenyuMcpServerManager).removeMcpServer("/mcp/old");
+ }
+
@Test
void testHandlerRuleWithValidData() {
RuleData ruleData = new RuleData();