Copilot commented on code in PR #6163:
URL: https://github.com/apache/shenyu/pull/6163#discussion_r2357460697


##########
shenyu-client/shenyu-client-mcp/src/main/java/org/apache/shenyu/client/mcp/common/constants/OpenApiConstants.java:
##########
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.client.mcp.common.constants;
+
+/**
+ * openApi constants.
+ */
+public class OpenApiConstants {
+
+    /**
+     * the version of openApi key.
+     */
+    public static final String OPEN_API_VERSION_KEY = "openapi";
+
+    /**
+     * the info of openApi key.
+     */
+    public static final String OPEN_API_INFO_KEY = "info";
+
+    /**
+     * the title of info key.
+     */
+    public static final String OPEN_API_INFO_TITLE_KEY = "title";
+
+    /**
+     * the description of info key.
+     */
+    public static final String OPEN_API_INFO_DESCRIPTION_KEY = "description";
+
+    /**
+     * the version of info key.
+     */
+    public static final String OPEN_API_INFO_VERSION_KEY = "version";
+
+    /**
+     * the server of openApi key.
+     */
+    public static final String OPEN_API_SERVER_KEY = "server";
+
+    /**
+     * the url of openApi server.
+     */
+    public static final String OPEN_API_SERVER_URL_KEY = "url";
+
+    /**
+     * the path of openApi key.
+     */
+    public static final String OPEN_API_PATH_KEY = "paths";
+
+    /**
+     * the summary of method key.
+     */
+    public static final String OPEN_API_PATH_PATH_METHOD_SUMMARY_KEY = 
"summary";
+
+    /**
+     * the description of method key.
+     */
+    public static final String OPEN_API_PATH_PATH_METHOD_DESCRIPTION_KEY = 
"description";
+
+    /**
+     * the operationId of method key.
+     */
+    public static final String OPEN_API_PATH_PATH_METHOD_OPERATION_ID_KEY = 
"operationId";
+
+    /**
+     * the tag of method key.
+     */
+    public static final String OPEN_API_PATH_PATH_METHOD_TAG_KEY = "tag";
+
+    /**
+     * the parameters of method key.
+     */
+    public static final String OPEN_API_PATH_PATH_METHOD_PARAMETERS_KEY = 
"parameters";
+
+    /**
+     * the name of parameter key.
+     */
+    public static final String OPEN_API_PATH_PATH_METHOD_PARAMETERS_NAME_KEY = 
"name";
+
+    /**
+     * the location of parameter key.
+     */
+    public static final String OPEN_API_PATH_PATH_METHOD_PARAMETERS_IN_KEY = 
"in";
+
+    /**
+     * the description of parameter key.
+     */
+    public static final String 
OPEN_API_PATH_PATH_METHOD_PARAMETERS_DESCRIPTION_KEY = "description";
+
+    /**
+     * the required of parameter key.
+     */
+    public static final String 
OPEN_API_PATH_PATH_METHOD_PARAMETERS_REQUIRED_KEY = "description";

Review Comment:
   The constant value should be 'required' instead of 'description' as this 
represents the required field of a parameter, not its description.
   ```suggestion
       public static final String 
OPEN_API_PATH_PATH_METHOD_PARAMETERS_REQUIRED_KEY = "required";
   ```



##########
shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-mcp/src/main/java/org/apache/shenyu/springboot/starter/client/mcp/ShenyuMcpClientConfiguration.java:
##########
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.springboot.starter.client.mcp;
+
+import org.apache.shenyu.client.mcp.McpServiceEventListener;
+import org.apache.shenyu.common.utils.VersionUtils;
+import org.apache.shenyu.register.client.api.ShenyuClientRegisterRepository;
+import org.apache.shenyu.register.common.config.ShenyuClientConfig;
+import 
org.apache.shenyu.springboot.starter.client.common.config.ShenyuClientCommonBeanConfiguration;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * The type shenyu apache mcp client configuration.
+ */
+
+@Configuration
+@ImportAutoConfiguration(ShenyuClientCommonBeanConfiguration.class)
+@ConditionalOnProperty(value = "shenyu.register.enabled", matchIfMissing = 
true, havingValue = "true")
+public class ShenyuMcpClientConfiguration {
+
+    static {
+        VersionUtils.checkDuplicate(ShenyuMcpClientConfiguration.class);
+    }
+
+    /**
+     * Apache mcp service bean listener.
+     *
+     * @param clientConfig the client config
+     * @param shenyuClientRegisterRepository the shenyu client register 
repository
+     * @return the apache dubbo service bean listener

Review Comment:
   The return type documentation incorrectly mentions 'apache dubbo service 
bean listener' but should reference 'MCP service event listener' since this is 
for MCP, not Dubbo.
   ```suggestion
        * @return the MCP service event listener
   ```



##########
shenyu-client/shenyu-client-mcp/src/main/java/org/apache/shenyu/client/mcp/McpServiceEventListener.java:
##########
@@ -0,0 +1,256 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.client.mcp;
+
+import com.google.gson.JsonObject;
+import io.swagger.v3.oas.annotations.servers.Server;
+import org.apache.commons.lang3.StringUtils;
+import 
org.apache.shenyu.client.core.client.AbstractContextRefreshedEventListener;
+import org.apache.shenyu.client.mcp.common.annotation.ShenyuMcpClient;
+import org.apache.shenyu.client.mcp.generator.McpOpenApiGenerator;
+import org.apache.shenyu.client.mcp.generator.McpToolsRegisterDTOGenerator;
+import org.apache.shenyu.common.enums.ApiHttpMethodEnum;
+import org.apache.shenyu.common.enums.RpcTypeEnum;
+import org.apache.shenyu.register.client.api.ShenyuClientRegisterRepository;
+import org.apache.shenyu.register.common.config.ShenyuClientConfig;
+import org.apache.shenyu.register.common.dto.McpToolsRegisterDTO;
+import org.apache.shenyu.register.common.dto.MetaDataRegisterDTO;
+import org.apache.shenyu.register.common.dto.URIRegisterDTO;
+import org.javatuples.Sextet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.aop.support.AopUtils;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Mcp service event Listener.
+ */
+public class McpServiceEventListener extends 
AbstractContextRefreshedEventListener<Object, ShenyuMcpClient> {
+
+    private static final Logger log = 
LoggerFactory.getLogger(McpServiceEventListener.class);
+
+    /**
+     * Instantiates a new context refreshed event listener.
+     *
+     * @param clientConfig                   the shenyu client config
+     * @param shenyuClientRegisterRepository the shenyuClientRegisterRepository
+     */
+    public McpServiceEventListener(final ShenyuClientConfig clientConfig, 
final ShenyuClientRegisterRepository shenyuClientRegisterRepository) {
+        super(clientConfig, shenyuClientRegisterRepository);
+    }
+
+    @Override
+    protected Sextet<String[], String, String, ApiHttpMethodEnum[], 
RpcTypeEnum, String> buildApiDocSextet(final Method method, final Annotation 
annotation, final Map<String, Object> beans) {
+        return null;
+    }
+
+    @Override
+    protected Map<String, Object> getBeans(final ApplicationContext context) {
+        Map<String, Object> controllerBeans = 
context.getBeansWithAnnotation(Controller.class);
+        return controllerBeans.entrySet().stream()
+                .filter(entry -> {
+                    Object bean = entry.getValue();
+
+                    Class<?> targetClass = AopUtils.getTargetClass(bean);
+
+                    return 
targetClass.isAnnotationPresent(ShenyuMcpClient.class);
+                })
+                .collect(Collectors.toMap(Map.Entry::getKey, 
Map.Entry::getValue));
+    }
+
+    @Override
+    protected URIRegisterDTO buildURIRegisterDTO(final ApplicationContext 
context, final Map<String, Object> beans, final String namespaceId) {
+        return null;
+    }
+
+    @Override
+    protected String getClientName() {
+        return RpcTypeEnum.MCP.getName();
+    }
+
+    @Override
+    protected void handleClass(final Class<?> clazz, final Object bean, final 
ShenyuMcpClient beanShenyuClient, final String superPath) {
+    }
+
+    @Override
+    protected void handleMethod(final Object bean, final Class<?> clazz, final 
ShenyuMcpClient beanShenyuClient, final Method method, final String superPath) {
+        List<String> namespaceIds = this.getNamespace();
+        ShenyuMcpClient classMcpClient;
+        if (clazz.isAnnotationPresent(ShenyuMcpClient.class)) {
+            classMcpClient = clazz.getAnnotation(ShenyuMcpClient.class);
+        } else {
+            return;
+        }
+        ShenyuMcpClient methodMcpClient;
+        if (method.isAnnotationPresent(ShenyuMcpClient.class)) {
+            methodMcpClient = method.getAnnotation(ShenyuMcpClient.class);
+        } else {
+            return;
+        }
+
+        List<String> mergeUrls = findMergeUrl(clazz, method);
+        mergeUrls.forEach(url -> {
+            namespaceIds.forEach(namespaceId -> 
getPublisher().publishEvent(buildMcpToolsRegisterDTO(bean, clazz, 
classMcpClient, methodMcpClient, superPath, method, url, namespaceId)));
+        });
+    }
+
+    @Override
+    protected String buildApiSuperPath(final Class<?> clazz, final 
ShenyuMcpClient beanShenyuClient) {
+        Server[] servers = beanShenyuClient.definition().servers();
+        if (servers.length != 1) {
+            log.warn("The shenyuMcp service supports only a single server 
entry. Please ensure that only one server is configured");
+        }
+        String superUrl = servers[0].url();
+        if (StringUtils.isBlank(superUrl)) {
+            return superUrl;
+        }
+        return "";

Review Comment:
   The logic is inverted. When superUrl is blank, it returns the blank value, 
but when it's not blank, it returns an empty string. This should return 
superUrl when it's not blank and empty string when it is blank.
   ```suggestion
               return "";
           }
           return superUrl;
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to