Skip to content

Commit 97b7733

Browse files
committed
feat:mcp server autoRegister enhance
1 parent 0484d6a commit 97b7733

File tree

10 files changed

+551
-50
lines changed

10 files changed

+551
-50
lines changed
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.shenyu.client.core.utils;
19+
20+
import org.springframework.core.DefaultParameterNameDiscoverer;
21+
import org.springframework.core.ParameterNameDiscoverer;
22+
import org.springframework.web.bind.annotation.CookieValue;
23+
import org.springframework.web.bind.annotation.DeleteMapping;
24+
import org.springframework.web.bind.annotation.GetMapping;
25+
import org.springframework.web.bind.annotation.PatchMapping;
26+
import org.springframework.web.bind.annotation.PathVariable;
27+
import org.springframework.web.bind.annotation.PostMapping;
28+
import org.springframework.web.bind.annotation.PutMapping;
29+
import org.springframework.web.bind.annotation.RequestBody;
30+
import org.springframework.web.bind.annotation.RequestHeader;
31+
import org.springframework.web.bind.annotation.RequestMapping;
32+
import org.springframework.web.bind.annotation.RequestMethod;
33+
import org.springframework.web.bind.annotation.RequestParam;
34+
35+
36+
import java.lang.annotation.Annotation;
37+
import java.lang.reflect.Method;
38+
import java.lang.reflect.Parameter;
39+
import java.util.ArrayList;
40+
import java.util.Arrays;
41+
import java.util.List;
42+
import java.util.Objects;
43+
import java.util.stream.Collectors;
44+
45+
public class RequestMethodUtils {
46+
47+
private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
48+
49+
/**
50+
* get the support methodType from method .
51+
*
52+
* @param method method
53+
* @return the list of method Type
54+
*/
55+
public static List<String> getRequestMethodTypes(final Method method) {
56+
if (method.isAnnotationPresent(GetMapping.class)) {
57+
return List.of("GET");
58+
}
59+
if (method.isAnnotationPresent(PostMapping.class)) {
60+
return List.of("POST");
61+
}
62+
if (method.isAnnotationPresent(PutMapping.class)) {
63+
return List.of("PUT");
64+
}
65+
if (method.isAnnotationPresent(DeleteMapping.class)) {
66+
return List.of("DELETE");
67+
}
68+
if (method.isAnnotationPresent(PatchMapping.class)) {
69+
return List.of("PATCH");
70+
}
71+
if (method.isAnnotationPresent(RequestMapping.class)) {
72+
RequestMapping rm = method.getAnnotation(RequestMapping.class);
73+
RequestMethod[] requestMethods = rm.method();
74+
if (requestMethods.length == 0) {
75+
return List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD");
76+
}
77+
return Arrays.stream(requestMethods)
78+
.map(Enum::name)
79+
.collect(Collectors.toList());
80+
}
81+
return List.of();
82+
}
83+
84+
/**
85+
* get the parameter position list .
86+
*
87+
* @param method method
88+
* @return positionList
89+
*/
90+
public static List<String> getParameterPositions(final Method method) {
91+
List<String> positions = new ArrayList<>();
92+
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
93+
94+
for (int i = 0; i < parameterAnnotations.length; i++) {
95+
Annotation[] annotations = parameterAnnotations[i];
96+
97+
String position = "query";
98+
99+
for (Annotation annotation : annotations) {
100+
if (annotation instanceof PathVariable) {
101+
position = "path";
102+
break;
103+
} else if (annotation instanceof RequestParam) {
104+
position = "query";
105+
break;
106+
} else if (annotation instanceof RequestBody) {
107+
position = "body";
108+
break;
109+
} else if (annotation instanceof RequestHeader) {
110+
position = "header";
111+
break;
112+
} else if (annotation instanceof CookieValue) {
113+
position = "cookie";
114+
break;
115+
}
116+
}
117+
118+
positions.add(position);
119+
}
120+
121+
return positions;
122+
}
123+
124+
/**
125+
* get the parameter names .
126+
*
127+
* @param method method
128+
* @return the arr of parameter names
129+
*/
130+
public static String[] getParameterNames(final Method method) {
131+
Parameter[] parameters = method.getParameters();
132+
String[] namesFromDiscoverer = PARAMETER_NAME_DISCOVERER.getParameterNames(method);
133+
134+
String[] result = new String[parameters.length];
135+
136+
for (int i = 0; i < parameters.length; i++) {
137+
// try to obtain the name from spring annotation
138+
String nameFromAnnotation = getNameFromSpringAnnotation(parameters[i].getAnnotations());
139+
140+
if (Objects.nonNull(nameFromAnnotation) && !nameFromAnnotation.isEmpty()) {
141+
result[i] = nameFromAnnotation;
142+
} else if (Objects.nonNull(namesFromDiscoverer) && namesFromDiscoverer.length > i) {
143+
result[i] = namesFromDiscoverer[i];
144+
} else {
145+
result[i] = "arg" + i;
146+
}
147+
}
148+
return result;
149+
}
150+
151+
private static String getNameFromSpringAnnotation(final Annotation[] annotations) {
152+
for (Annotation annotation : annotations) {
153+
if (annotation instanceof RequestParam requestParam) {
154+
if (!requestParam.name().isEmpty()) {
155+
return requestParam.name();
156+
}
157+
if (!requestParam.value().isEmpty()) {
158+
return requestParam.value();
159+
}
160+
} else if (annotation instanceof PathVariable pathVariable) {
161+
if (!pathVariable.name().isEmpty()) {
162+
return pathVariable.name();
163+
}
164+
if (!pathVariable.value().isEmpty()) {
165+
return pathVariable.value();
166+
}
167+
} else if (annotation instanceof RequestHeader requestHeader) {
168+
if (!requestHeader.name().isEmpty()) {
169+
return requestHeader.name();
170+
}
171+
if (!requestHeader.value().isEmpty()) {
172+
return requestHeader.value();
173+
}
174+
} else if (annotation instanceof CookieValue cookieValue) {
175+
if (!cookieValue.name().isEmpty()) {
176+
return cookieValue.name();
177+
}
178+
if (!cookieValue.value().isEmpty()) {
179+
return cookieValue.value();
180+
}
181+
}
182+
}
183+
return null;
184+
}
185+
186+
}

shenyu-client/shenyu-client-mcp/shenyu-client-mcp-common/src/main/java/org/apache/shenyu/client/mcp/common/annotation/ShenyuMcpRequestConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@
3333
* bodyJson.
3434
* @return the bodyJson
3535
*/
36-
String bodyJson() default "";
36+
String bodyToJson() default "false";
3737

3838
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.shenyu.client.mcp.common.dto;
19+
20+
import java.util.HashMap;
21+
import java.util.Map;
22+
23+
/**
24+
* the shenyu mcp request config object.
25+
*/
26+
public class ShenyuMcpRequestConfig {
27+
28+
private Map<String, String> headers = new HashMap<>();
29+
30+
private String bodyToJson;
31+
32+
public ShenyuMcpRequestConfig() {
33+
}
34+
35+
/**
36+
* get headers.
37+
*
38+
* @return headers
39+
*/
40+
public Map<String, String> getHeaders() {
41+
return headers;
42+
}
43+
44+
/**
45+
* set headers.
46+
*
47+
* @param headers headers
48+
*/
49+
public void setHeaders(final Map<String, String> headers) {
50+
this.headers = headers;
51+
}
52+
53+
/**
54+
* get bodyToJson.
55+
*
56+
* @return bodyToJson
57+
*/
58+
public String getBodyToJson() {
59+
return bodyToJson;
60+
}
61+
62+
/**
63+
* set bodyToJson.
64+
*
65+
* @param bodyToJson bodyToJson
66+
*/
67+
public void setBodyToJson(final String bodyToJson) {
68+
this.bodyToJson = bodyToJson;
69+
}
70+
}

0 commit comments

Comments
 (0)