chore: downgrade to spring boot 3.5
All checks were successful
Deploy to OCIWP / deploy (push) Successful in 2m43s
All checks were successful
Deploy to OCIWP / deploy (push) Successful in 2m43s
This commit is contained in:
@@ -12,7 +12,7 @@ dependencies {
|
||||
api 'io.github.resilience4j:resilience4j-circuitbreaker:2.2.0'
|
||||
api 'io.github.resilience4j:resilience4j-ratelimiter'
|
||||
api 'io.github.resilience4j:resilience4j-retry:2.2.0'
|
||||
api 'org.springframework.boot:spring-boot-starter-aop:3.3.0'
|
||||
api 'org.springframework.boot:spring-boot-starter-aop'
|
||||
|
||||
api 'org.springframework.boot:spring-boot-starter-jdbc'
|
||||
api 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
|
||||
@@ -26,6 +26,7 @@ dependencies {
|
||||
api 'com.fasterxml.jackson.core:jackson-databind:2.17.1'
|
||||
api 'com.networknt:json-schema-validator:3.0.0'
|
||||
api 'org.springframework.ai:spring-ai-starter-mcp-server-webmvc'
|
||||
api 'org.springaicommunity:mcp-annotations:0.9.0'
|
||||
api 'org.springframework.kafka:spring-kafka:3.2.0'
|
||||
api 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.ai.mcp.annotation.McpTool;
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ToolSlaMonitoringAspect {
|
||||
private final McpProperties mcpProperties;
|
||||
|
||||
// @McpTool 어노테이션이 붙은 모든 비즈니스 툴 메서드 실행을 가로챕니다.
|
||||
@Around("@annotation(org.springframework.ai.mcp.annotation.McpTool)")
|
||||
@Around("@annotation(org.springaicommunity.mcp.annotation.McpTool)")
|
||||
public Object monitorToolSla(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
|
||||
@@ -10,6 +10,7 @@ import io.shinhanlife.dap.lib.mcp.ToolRegistryHeartbeatSender;
|
||||
import io.shinhanlife.dap.lib.mcp.McpRequestHeaderContext;
|
||||
import io.shinhanlife.dap.lib.mcp.McpRequestHeaders;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
@@ -46,12 +47,14 @@ public class ToolPodMcpToolSynchronizer {
|
||||
McpSchema.Tool mcpTool = McpSchema.Tool.builder()
|
||||
.name(tool.getName())
|
||||
.description(tool.getDescription() == null || tool.getDescription().isBlank() ? tool.getName() + " Tool" : tool.getDescription())
|
||||
.inputSchema(tool.getParametersSchema() == null ? emptySchema() : tool.getParametersSchema())
|
||||
.annotations(McpSchema.ToolAnnotations.builder()
|
||||
.readOnlyHint(Boolean.TRUE.equals(tool.getReadOnlyHint()))
|
||||
.destructiveHint(Boolean.TRUE.equals(tool.getDestructiveHint()))
|
||||
.idempotentHint(Boolean.TRUE.equals(tool.getIdempotentHint()))
|
||||
.openWorldHint(Boolean.TRUE.equals(tool.getOpenWorldHint())).build())
|
||||
.inputSchema(toJsonSchema(tool.getParametersSchema()))
|
||||
.annotations(new McpSchema.ToolAnnotations(
|
||||
tool.getDisplayName(),
|
||||
tool.getReadOnlyHint(),
|
||||
tool.getDestructiveHint(),
|
||||
tool.getIdempotentHint(),
|
||||
tool.getOpenWorldHint(),
|
||||
null))
|
||||
.build();
|
||||
return McpServerFeatures.SyncToolSpecification.builder().tool(mcpTool)
|
||||
.callHandler((context, request) -> invoke(tool.getName(), McpRequestHeaderContext.current(), request.arguments())).build();
|
||||
@@ -83,4 +86,19 @@ public class ToolPodMcpToolSynchronizer {
|
||||
schema.put("additionalProperties", false);
|
||||
return schema;
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
private McpSchema.JsonSchema toJsonSchema(Map<String, Object> source) {
|
||||
Map<String, Object> schema = source == null ? emptySchema() : source;
|
||||
return new McpSchema.JsonSchema(
|
||||
String.valueOf(schema.getOrDefault("type", "object")),
|
||||
schema.get("properties") instanceof Map<?, ?> properties
|
||||
? (Map<String, Object>) properties : Map.of(),
|
||||
schema.get("required") instanceof List<?> required
|
||||
? (List<String>) required : List.of(),
|
||||
schema.get("additionalProperties") instanceof Boolean additionalProperties
|
||||
? additionalProperties : Boolean.TRUE,
|
||||
schema.get("$defs") instanceof Map<?, ?> defs ? (Map<String, Object>) defs : Map.of(),
|
||||
schema.get("definitions") instanceof Map<?, ?> definitions
|
||||
? (Map<String, Object>) definitions : Map.of());
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ package io.shinhanlife.dap.lib.mcp;
|
||||
* </pre>
|
||||
*/
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.ai.mcp.annotation.McpTool;
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import io.shinhanlife.dap.lib.annotation.ToolHint;
|
||||
import io.shinhanlife.dap.lib.config.McpProperties;
|
||||
import io.shinhanlife.dap.mcc.dto.ToolMetadata;
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.shinhanlife.dap.lib.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
|
||||
import org.springframework.ai.mcp.annotation.McpToolParam;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.shinhanlife.dap.lib.util;
|
||||
|
||||
|
||||
import org.springframework.ai.mcp.annotation.McpToolParam;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -227,7 +227,7 @@ public class ToolScaffolder {
|
||||
String serviceInterfaceContent = """
|
||||
package %s.usecase;
|
||||
|
||||
import org.springframework.ai.mcp.annotation.McpTool;
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import io.shinhanlife.dap.lib.annotation.ToolHint;
|
||||
import %s.dto.%sRequest;
|
||||
import %s.dto.%sResponse;
|
||||
|
||||
@@ -18,7 +18,7 @@ public class ToolSchemaResolver {
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
public Map<String, Object> resolve(org.springframework.ai.mcp.annotation.McpTool function, ToolHint hint, Class<?> requestType) {
|
||||
public Map<String, Object> resolve(org.springaicommunity.mcp.annotation.McpTool function, ToolHint hint, Class<?> requestType) {
|
||||
if (hint != null && !hint.inputSchemaResource().isBlank()) {
|
||||
return loadResource(hint.inputSchemaResource());
|
||||
}
|
||||
@@ -31,7 +31,7 @@ public class ToolSchemaResolver {
|
||||
* ToolHint.outputSchemaResource()가 있으면 classpath JSON 파일에서 로드하고,
|
||||
* 없으면 responseType DTO를 분석하여 자동 생성합니다.
|
||||
*/
|
||||
public Map<String, Object> resolveOutput(org.springframework.ai.mcp.annotation.McpTool function, Class<?> responseType, ToolHint hint) {
|
||||
public Map<String, Object> resolveOutput(org.springaicommunity.mcp.annotation.McpTool function, Class<?> responseType, ToolHint hint) {
|
||||
if (hint != null && !hint.outputSchemaResource().isBlank()) {
|
||||
return loadResource(hint.outputSchemaResource());
|
||||
}
|
||||
@@ -42,7 +42,7 @@ public class ToolSchemaResolver {
|
||||
* Resolves an explicitly declared response schema.
|
||||
* Response schemas are opt-in so existing tools keep their current response behavior.
|
||||
*/
|
||||
public Map<String, Object> resolveOutput(org.springframework.ai.mcp.annotation.McpTool function, Class<?> responseType) {
|
||||
public Map<String, Object> resolveOutput(org.springaicommunity.mcp.annotation.McpTool function, Class<?> responseType) {
|
||||
// Object, Map 등 구체적인 DTO가 아닌 경우 검증 스킵
|
||||
if (responseType == null
|
||||
|| responseType == Object.class
|
||||
@@ -57,7 +57,7 @@ public class ToolSchemaResolver {
|
||||
/**
|
||||
* Retained for callers that use only explicit output schemas.
|
||||
*/
|
||||
public Map<String, Object> resolveOutput(org.springframework.ai.mcp.annotation.McpTool function) {
|
||||
public Map<String, Object> resolveOutput(org.springaicommunity.mcp.annotation.McpTool function) {
|
||||
return resolveOutput(function, null);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ package io.shinhanlife.dap.mcc.presentation;
|
||||
*/
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.networknt.schema.Error;
|
||||
import org.springframework.ai.mcp.annotation.McpTool;
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import io.shinhanlife.dap.lib.validation.ToolArgumentSchemaValidator;
|
||||
import io.shinhanlife.dap.lib.config.McpProperties;
|
||||
import io.shinhanlife.dap.mcc.dto.ToolMetadata;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.shinhanlife.dap.lib.util;
|
||||
|
||||
|
||||
import org.springframework.ai.mcp.annotation.McpToolParam;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.ai.mcp.annotation.McpTool;
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
|
||||
class ToolSchemaResolverTest {
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ class ToolSourceUpdaterTest {
|
||||
Files.createDirectories(source.getParent());
|
||||
Files.writeString(source, """
|
||||
package example;
|
||||
import org.springframework.ai.mcp.annotation.McpTool;
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import io.shinhanlife.dap.lib.annotation.ToolHint;
|
||||
interface SampleUseCase {
|
||||
@McpTool(name = "oth.cmm.sample.search", description = "old")
|
||||
|
||||
@@ -90,7 +90,7 @@ class McpToolNameValidatorTest {
|
||||
Files.writeString(source, """
|
||||
package example;
|
||||
|
||||
import org.springframework.ai.mcp.annotation.McpTool;
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
|
||||
class %s {
|
||||
@McpTool(name = "%s")
|
||||
|
||||
Reference in New Issue
Block a user