This is an automated email from the ASF dual-hosted git repository.
Aias00 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 d407d4ffc4 fix(admin): keep every HTTP method when importing a path as
MCP tools (#7333)
d407d4ffc4 is described below
commit d407d4ffc4149344e9d93891e369389b81d93518
Author: Sean-Walker0 <[email protected]>
AuthorDate: Mon Sep 28 11:37:14 2026 +0800
fix(admin): keep every HTTP method when importing a path as MCP tools
(#7333)
buildShenyuMcpTool looped over the operations of each OpenAPI path but
put every tool into a single map keyed by the bare path, so each
operation overwrote the previous one and only the last HTTP method of a
multi-method path (GET+POST /users being the most standard OpenAPI
shape) survived as an MCP tool; the rest were silently dropped before
registration. The outer container is already a List of maps, so give
each operation its own single-entry map - the downstream generator
still receives the path as the entry key and now sees every operation.
The new test fails on current master (expected 2 tools but was 1) and
passes with this change.
Co-authored-by: Sean-Walker0
<[email protected]>
Co-authored-by: aias00 <[email protected]>
---
.../service/impl/SwaggerImportServiceImpl.java | 5 ++--
.../service/impl/SwaggerImportServiceImplTest.java | 31 ++++++++++++++++++++++
2 files changed, 34 insertions(+), 2 deletions(-)
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SwaggerImportServiceImpl.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SwaggerImportServiceImpl.java
index 81e31f0b39..a795602755 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SwaggerImportServiceImpl.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SwaggerImportServiceImpl.java
@@ -184,7 +184,6 @@ public class SwaggerImportServiceImpl implements
SwaggerImportService {
.orElse("default");
List<Map<String, ShenyuMcpTool>> maps =
result.computeIfAbsent(mainPath, k -> new ArrayList<>());
- Map<String, ShenyuMcpTool> toolMap = new HashMap<>();
Map<PathItem.HttpMethod, Operation> operationsMap =
pathItem.readOperationsMap();
for (Map.Entry<PathItem.HttpMethod, Operation> opEntry :
operationsMap.entrySet()) {
@@ -201,9 +200,11 @@ public class SwaggerImportServiceImpl implements
SwaggerImportService {
PathItem.HttpMethod httpMethod = opEntry.getKey();
tool.setMethod(httpMethod.name().toLowerCase());
+ // one entry per operation: a shared path-keyed map would keep
only the last HTTP method
+ Map<String, ShenyuMcpTool> toolMap = new HashMap<>();
toolMap.put(fullPath, tool);
+ maps.add(toolMap);
}
- maps.add(toolMap);
}
return result;
}
diff --git
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/impl/SwaggerImportServiceImplTest.java
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/impl/SwaggerImportServiceImplTest.java
index cb48e6f2b4..503aa4f7f7 100644
---
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/impl/SwaggerImportServiceImplTest.java
+++
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/impl/SwaggerImportServiceImplTest.java
@@ -37,11 +37,17 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.Operation;
+import io.swagger.v3.oas.models.PathItem;
+import io.swagger.v3.oas.models.Paths;
+import org.apache.shenyu.client.mcp.common.dto.ShenyuMcpTool;
import org.springframework.test.util.ReflectionTestUtils;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@@ -175,6 +181,31 @@ public class SwaggerImportServiceImplTest {
};
}
+ @Test
+ @SuppressWarnings("unchecked")
+ public void buildShenyuMcpToolKeepsEveryHttpMethodOfTheSamePath() throws
Exception {
+ OpenAPI openapi = new OpenAPI();
+ openapi.setPaths(new Paths());
+ PathItem pathItem = new PathItem();
+ pathItem.setGet(new Operation().operationId("listUsers"));
+ pathItem.setPost(new Operation().operationId("createUser"));
+ openapi.getPaths().addPathItem("/users", pathItem);
+
+ java.lang.reflect.Method build =
SwaggerImportServiceImpl.class.getDeclaredMethod("buildShenyuMcpTool",
OpenAPI.class);
+ build.setAccessible(true);
+ Map<String, java.util.List<Map<String, ShenyuMcpTool>>> result =
+ (Map<String, java.util.List<Map<String, ShenyuMcpTool>>>)
build.invoke(service, openapi);
+
+ java.util.List<Map<String, ShenyuMcpTool>> tools =
result.values().iterator().next();
+ assertEquals(2, tools.size(), "both operations of the same path must
become MCP tools");
+ java.util.Set<String> httpMethods = tools.stream()
+ .flatMap(toolMap -> toolMap.values().stream())
+ .map(ShenyuMcpTool::getMethod)
+ .collect(java.util.stream.Collectors.toSet());
+ assertEquals(new java.util.HashSet<>(Arrays.asList("get", "post")),
httpMethods);
+ }
+
+
private static final class RecordingDocManager implements DocManager {
private String docJson;