forked from kimhyungsik/ax_hub_mcp_tool
refactor: extract inline fully qualified class names to imports
This commit is contained in:
@@ -6,27 +6,14 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
import org.springframework.web.servlet.resource.NoResourceFoundException;
|
||||||
|
|
||||||
/**
|
|
||||||
* @package io.shinhanlife.axhub.common.mcp.exception
|
|
||||||
* @className GlobalExceptionHandler
|
|
||||||
* @description AX HUB 시스템 처리 클래스
|
|
||||||
* @author 김형식
|
|
||||||
* @create 2026.09.01
|
|
||||||
* <pre>
|
|
||||||
* ---------- 개정이력 ----------
|
|
||||||
* 수정일 수정자 수정내용
|
|
||||||
* ---------- -------- ---------------------------
|
|
||||||
* 2026.09.01 김형식 최초생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestControllerAdvice // 이 어노테이션이 전역 적용의 핵심입니다!
|
@RestControllerAdvice // 이 어노테이션이 전역 적용의 핵심입니다!
|
||||||
public class GlobalExceptionHandler {
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
@ExceptionHandler(org.springframework.web.servlet.resource.NoResourceFoundException.class)
|
@ExceptionHandler(NoResourceFoundException.class)
|
||||||
public ResponseEntity<Void> handleNoResourceFound(org.springframework.web.servlet.resource.NoResourceFoundException e) {
|
public ResponseEntity<Void> handleNoResourceFound(NoResourceFoundException e) {
|
||||||
log.warn(" [Gateway Not Found] 요청하신 리소스를 찾을 수 없습니다: {}", e.getResourcePath());
|
log.warn(" [Gateway Not Found] 요청하신 리소스를 찾을 수 없습니다: {}", e.getResourcePath());
|
||||||
return ResponseEntity.notFound().build();
|
return ResponseEntity.notFound().build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,24 +2,11 @@ package io.shinhanlife.axhub.biz.mcp.gateway;
|
|||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
|
||||||
/**
|
|
||||||
* @package io.shinhanlife.axhub.biz.mcp.gateway
|
|
||||||
* @className AxHubGatewayApplication
|
|
||||||
* @description AX HUB 시스템 처리 클래스
|
|
||||||
* @author 김형식
|
|
||||||
* @create 2026.09.01
|
|
||||||
* <pre>
|
|
||||||
* ---------- 개정이력 ----------
|
|
||||||
* 수정일 수정자 수정내용
|
|
||||||
* ---------- -------- ---------------------------
|
|
||||||
* 2026.09.01 김형식 최초생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.axhub.biz.mcp.gateway", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.axhub.biz.mcp.gateway", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
||||||
@org.springframework.boot.context.properties.ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.axhub.biz.mcp.gateway", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
@ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.axhub.biz.mcp.gateway", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
public class AxHubGatewayApplication {
|
public class AxHubGatewayApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
@@ -4,39 +4,29 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import io.shinhanlife.axhub.biz.mcp.adapter.dto.JsonRpcRequest;
|
import io.shinhanlife.axhub.biz.mcp.adapter.dto.JsonRpcRequest;
|
||||||
import io.shinhanlife.axhub.biz.mcp.adapter.dto.JsonRpcResponse;
|
import io.shinhanlife.axhub.biz.mcp.adapter.dto.JsonRpcResponse;
|
||||||
import io.shinhanlife.axhub.biz.mcp.adapter.dto.Params;
|
import io.shinhanlife.axhub.biz.mcp.adapter.dto.Params;
|
||||||
import io.shinhanlife.axhub.biz.mcp.gateway.dto.ToolMetadata;
|
|
||||||
import io.shinhanlife.axhub.biz.mcp.gateway.service.ExecuteService;
|
|
||||||
import io.shinhanlife.axhub.biz.mcp.gateway.config.GatewayFallbackProperties;
|
import io.shinhanlife.axhub.biz.mcp.gateway.config.GatewayFallbackProperties;
|
||||||
|
import io.shinhanlife.axhub.biz.mcp.gateway.dto.ToolMetadata;
|
||||||
import io.shinhanlife.axhub.biz.mcp.gateway.registry.RedisRegistryService;
|
import io.shinhanlife.axhub.biz.mcp.gateway.registry.RedisRegistryService;
|
||||||
|
import io.shinhanlife.axhub.biz.mcp.gateway.service.ExecuteService;
|
||||||
import io.shinhanlife.axhub.common.mcp.security.SecurityProperties;
|
import io.shinhanlife.axhub.common.mcp.security.SecurityProperties;
|
||||||
|
|
||||||
import org.springframework.core.ParameterizedTypeReference;
|
|
||||||
import org.springframework.web.client.RestClient;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.List;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.client.RestClient;
|
||||||
|
|
||||||
/**
|
|
||||||
* @package io.shinhanlife.axhub.biz.mcp.gateway.presentation
|
|
||||||
* @className McpRouterController
|
|
||||||
* @description AX HUB 시스템 처리 클래스
|
|
||||||
* @author 김형식
|
|
||||||
* @create 2026.09.01
|
|
||||||
* <pre>
|
|
||||||
* ---------- 개정이력 ----------
|
|
||||||
* 수정일 수정자 수정내용
|
|
||||||
* ---------- -------- ---------------------------
|
|
||||||
* 2026.09.01 김형식 최초생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/mcp/api/v1")
|
@RequestMapping("/mcp/api/v1")
|
||||||
@@ -72,8 +62,8 @@ public class McpRouterController {
|
|||||||
@RequestBody Map<String, Object> payload,
|
@RequestBody Map<String, Object> payload,
|
||||||
@RequestAttribute(value = "tenantId", required = false) String tenantId) {
|
@RequestAttribute(value = "tenantId", required = false) String tenantId) {
|
||||||
|
|
||||||
java.util.Map<String, Object> meta = new java.util.HashMap<>();
|
Map<String, Object> meta = new HashMap<>();
|
||||||
meta.put("traceId", traceId != null ? traceId : java.util.UUID.randomUUID().toString());
|
meta.put("traceId", traceId != null ? traceId : UUID.randomUUID().toString());
|
||||||
meta.put("agentId", agentId != null ? agentId : "UNKNOWN");
|
meta.put("agentId", agentId != null ? agentId : "UNKNOWN");
|
||||||
meta.put("userPrompt", userPrompt != null ? userPrompt : "");
|
meta.put("userPrompt", userPrompt != null ? userPrompt : "");
|
||||||
payload.put("meta", meta);
|
payload.put("meta", meta);
|
||||||
@@ -110,13 +100,13 @@ public class McpRouterController {
|
|||||||
List<ToolMetadata> activeTools = redisRegistryService.getAllTools()
|
List<ToolMetadata> activeTools = redisRegistryService.getAllTools()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(ToolMetadata::getVisible)
|
.filter(ToolMetadata::getVisible)
|
||||||
.collect(java.util.stream.Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
java.util.Set<String> knownTools = activeTools.stream()
|
Set<String> knownTools = activeTools.stream()
|
||||||
.map(ToolMetadata::getUid)
|
.map(ToolMetadata::getUid)
|
||||||
.collect(java.util.stream.Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
java.util.Set<String> fallbackUrls = new java.util.HashSet<>(gatewayFallbackProperties.getRoutes().values());
|
Set<String> fallbackUrls = new HashSet<>(gatewayFallbackProperties.getRoutes().values());
|
||||||
if (gatewayFallbackProperties.getDefaultUrl() != null) {
|
if (gatewayFallbackProperties.getDefaultUrl() != null) {
|
||||||
fallbackUrls.add(gatewayFallbackProperties.getDefaultUrl());
|
fallbackUrls.add(gatewayFallbackProperties.getDefaultUrl());
|
||||||
}
|
}
|
||||||
@@ -153,20 +143,20 @@ public class McpRouterController {
|
|||||||
List<ToolMetadata> tools = redisRegistryService.getAllTools()
|
List<ToolMetadata> tools = redisRegistryService.getAllTools()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(ToolMetadata::getVisible)
|
.filter(ToolMetadata::getVisible)
|
||||||
.collect(java.util.stream.Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
StringBuilder md = new StringBuilder();
|
StringBuilder md = new StringBuilder();
|
||||||
md.append("# \uD83E\uDD16 Shinhan AI Tool Catalog\n\n");
|
md.append("# \uD83E\uDD16 Shinhan AI Tool Catalog\n\n");
|
||||||
md.append("**총 등록된 툴:** ").append(tools.size()).append("개\n");
|
md.append("**총 등록된 툴:** ").append(tools.size()).append("개\n");
|
||||||
java.time.format.DateTimeFormatter formatter = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
md.append("**마지막 업데이트:** ").append(java.time.LocalDateTime.now().format(formatter)).append("\n\n");
|
md.append("**마지막 업데이트:** ").append(LocalDateTime.now().format(formatter)).append("\n\n");
|
||||||
md.append("---\n\n");
|
md.append("---\n\n");
|
||||||
|
|
||||||
// Group by Domain Group
|
// Group by Domain Group
|
||||||
Map<String, List<ToolMetadata>> groupedTools = new java.util.HashMap<>();
|
Map<String, List<ToolMetadata>> groupedTools = new HashMap<>();
|
||||||
for (ToolMetadata tool : tools) {
|
for (ToolMetadata tool : tools) {
|
||||||
String group = tool.getCategoryKey() != null ? tool.getCategoryKey() : "기타 (Others)";
|
String group = tool.getCategoryKey() != null ? tool.getCategoryKey() : "기타 (Others)";
|
||||||
groupedTools.computeIfAbsent(group, k -> new java.util.ArrayList<>()).add(tool);
|
groupedTools.computeIfAbsent(group, k -> new ArrayList<>()).add(tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Map.Entry<String, List<ToolMetadata>> entry : groupedTools.entrySet()) {
|
for (Map.Entry<String, List<ToolMetadata>> entry : groupedTools.entrySet()) {
|
||||||
|
|||||||
@@ -2,12 +2,15 @@ package io.shinhanlife.axhub.biz.mcp.gateway.presentation;
|
|||||||
|
|
||||||
import io.shinhanlife.axhub.common.util.PodScaffolder;
|
import io.shinhanlife.axhub.common.util.PodScaffolder;
|
||||||
import io.shinhanlife.axhub.common.util.ToolScaffolder;
|
import io.shinhanlife.axhub.common.util.ToolScaffolder;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import io.shinhanlife.axhub.common.util.ToolSourceUpdater;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/scaffold")
|
@RequestMapping("/api/v1/scaffold")
|
||||||
@@ -23,7 +26,7 @@ public class ScaffoldingController {
|
|||||||
String author = req.get("author");
|
String author = req.get("author");
|
||||||
if (author == null || author.trim().isEmpty()) author = System.getProperty("user.name");
|
if (author == null || author.trim().isEmpty()) author = System.getProperty("user.name");
|
||||||
String date = req.get("date");
|
String date = req.get("date");
|
||||||
if (date == null || date.trim().isEmpty()) date = java.time.LocalDate.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyy.MM.dd"));
|
if (date == null || date.trim().isEmpty()) date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd"));
|
||||||
|
|
||||||
return PodScaffolder.scaffoldPod(moduleName, port, shortName, author, date);
|
return PodScaffolder.scaffoldPod(moduleName, port, shortName, author, date);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -43,7 +46,7 @@ public class ScaffoldingController {
|
|||||||
String author = req.get("author");
|
String author = req.get("author");
|
||||||
if (author == null || author.trim().isEmpty()) author = System.getProperty("user.name");
|
if (author == null || author.trim().isEmpty()) author = System.getProperty("user.name");
|
||||||
String date = req.get("date");
|
String date = req.get("date");
|
||||||
if (date == null || date.trim().isEmpty()) date = java.time.LocalDate.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyy.MM.dd"));
|
if (date == null || date.trim().isEmpty()) date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd"));
|
||||||
boolean register = Boolean.parseBoolean(req.getOrDefault("register", "true"));
|
boolean register = Boolean.parseBoolean(req.getOrDefault("register", "true"));
|
||||||
|
|
||||||
return ToolScaffolder.scaffold(baseName, interfaceId, description, group, routingType, moduleName, author, date, register);
|
return ToolScaffolder.scaffold(baseName, interfaceId, description, group, routingType, moduleName, author, date, register);
|
||||||
@@ -61,7 +64,7 @@ public class ScaffoldingController {
|
|||||||
boolean register = Boolean.parseBoolean(req.getOrDefault("register", "true"));
|
boolean register = Boolean.parseBoolean(req.getOrDefault("register", "true"));
|
||||||
Boolean requiresApproval = req.containsKey("requiresApproval") ? Boolean.parseBoolean(req.get("requiresApproval")) : null;
|
Boolean requiresApproval = req.containsKey("requiresApproval") ? Boolean.parseBoolean(req.get("requiresApproval")) : null;
|
||||||
|
|
||||||
io.shinhanlife.axhub.common.util.ToolSourceUpdater.updateToolSource(toolName, domainGroup, description, register, requiresApproval);
|
ToolSourceUpdater.updateToolSource(toolName, domainGroup, description, register, requiresApproval);
|
||||||
return "성공";
|
return "성공";
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return "오류 발생: " + e.getMessage();
|
return "오류 발생: " + e.getMessage();
|
||||||
|
|||||||
@@ -2,29 +2,15 @@ package io.shinhanlife.axhub.biz.mcp.gateway.service;
|
|||||||
|
|
||||||
import io.shinhanlife.axhub.biz.mcp.adapter.dto.Params;
|
import io.shinhanlife.axhub.biz.mcp.adapter.dto.Params;
|
||||||
import io.shinhanlife.axhub.biz.mcp.gateway.dto.ToolMetadata;
|
import io.shinhanlife.axhub.biz.mcp.gateway.dto.ToolMetadata;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.client.RestClient;
|
import org.springframework.web.client.RestClient;
|
||||||
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package io.shinhanlife.axhub.biz.mcp.gateway.service
|
|
||||||
* @className ExecuteService
|
|
||||||
* @description AX HUB 시스템 처리 클래스
|
|
||||||
* @author 김형식
|
|
||||||
* @create 2026.09.01
|
|
||||||
* <pre>
|
|
||||||
* ---------- 개정이력 ----------
|
|
||||||
* 수정일 수정자 수정내용
|
|
||||||
* ---------- -------- ---------------------------
|
|
||||||
* 2026.09.01 김형식 최초생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@@ -83,7 +69,7 @@ public class ExecuteService {
|
|||||||
.uri(url)
|
.uri(url)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
// TODO: Use actual tenant's key
|
// TODO: Use actual tenant's key
|
||||||
.header("X-Trace-Id", java.util.UUID.randomUUID().toString())
|
.header("X-Trace-Id", UUID.randomUUID().toString())
|
||||||
.body(payload)
|
.body(payload)
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.body(Object.class);
|
.body(Object.class);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.shinhanlife.axhub.biz.mcp.tool.aop;
|
|||||||
|
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction;
|
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction;
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.config.McpProperties;
|
import io.shinhanlife.axhub.biz.mcp.tool.config.McpProperties;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
@@ -11,22 +12,6 @@ import org.aspectj.lang.reflect.MethodSignature;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StopWatch;
|
import org.springframework.util.StopWatch;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @package io.shinhanlife.axhub.biz.mcp.tool.aop
|
|
||||||
* @className ToolSlaMonitoringAspect
|
|
||||||
* @description AX HUB 시스템 처리 클래스
|
|
||||||
* @author 김형식
|
|
||||||
* @create 2026.09.01
|
|
||||||
* <pre>
|
|
||||||
* ---------- 개정이력 ----------
|
|
||||||
* 수정일 수정자 수정내용
|
|
||||||
* ---------- -------- ---------------------------
|
|
||||||
* 2026.09.01 김형식 최초생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Aspect
|
@Aspect
|
||||||
@Component
|
@Component
|
||||||
@@ -36,7 +21,7 @@ public class ToolSlaMonitoringAspect {
|
|||||||
private final McpProperties mcpProperties;
|
private final McpProperties mcpProperties;
|
||||||
|
|
||||||
// @McpFunction 어노테이션이 붙은 모든 비즈니스 툴 메서드 실행을 가로챕니다.
|
// @McpFunction 어노테이션이 붙은 모든 비즈니스 툴 메서드 실행을 가로챕니다.
|
||||||
@Around("@annotation(io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction)")
|
@Around("@annotation(McpFunction)")
|
||||||
public Object monitorToolSla(ProceedingJoinPoint joinPoint) throws Throwable {
|
public Object monitorToolSla(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||||
Method method = signature.getMethod();
|
Method method = signature.getMethod();
|
||||||
|
|||||||
@@ -1,53 +1,38 @@
|
|||||||
package io.shinhanlife.axhub.biz.mcp.tool.presentation;
|
package io.shinhanlife.axhub.biz.mcp.tool.presentation;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.networknt.schema.JsonSchema;
|
import com.networknt.schema.JsonSchema;
|
||||||
import com.networknt.schema.JsonSchemaFactory;
|
import com.networknt.schema.JsonSchemaFactory;
|
||||||
import com.networknt.schema.SpecVersion;
|
import com.networknt.schema.SpecVersion;
|
||||||
import com.networknt.schema.ValidationMessage;
|
import com.networknt.schema.ValidationMessage;
|
||||||
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpTool;
|
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction;
|
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction;
|
||||||
|
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpTool;
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.config.McpProperties;
|
import io.shinhanlife.axhub.biz.mcp.tool.config.McpProperties;
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.dto.ToolMetadata;
|
import io.shinhanlife.axhub.biz.mcp.tool.dto.ToolMetadata;
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.service.ToolRegistryHeartbeatSender;
|
import io.shinhanlife.axhub.biz.mcp.tool.service.ToolRegistryHeartbeatSender;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.util.JsonSchemaGenerator;
|
import io.shinhanlife.axhub.biz.mcp.tool.util.JsonSchemaGenerator;
|
||||||
import org.springframework.util.ClassUtils;
|
import java.lang.reflect.Method;
|
||||||
import org.springframework.aop.support.AopUtils;
|
import java.util.ArrayList;
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.aop.support.AopUtils;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
|
||||||
* @package io.shinhanlife.axhub.biz.mcp.tool.presentation
|
|
||||||
* @className BusinessToolController
|
|
||||||
* @description AX HUB 시스템 처리 클래스
|
|
||||||
* @author 김형식
|
|
||||||
* @create 2026.09.01
|
|
||||||
* <pre>
|
|
||||||
* ---------- 개정이력 ----------
|
|
||||||
* 수정일 수정자 수정내용
|
|
||||||
* ---------- -------- ---------------------------
|
|
||||||
* 2026.09.01 김형식 최초생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/")
|
@RequestMapping("/")
|
||||||
@@ -67,8 +52,8 @@ public class BusinessToolController {
|
|||||||
|
|
||||||
// JSON RPC 기반 단일 라우팅 엔드포인트
|
// JSON RPC 기반 단일 라우팅 엔드포인트
|
||||||
@PostMapping("/mcp/api/v1/tools/call")
|
@PostMapping("/mcp/api/v1/tools/call")
|
||||||
public org.springframework.http.ResponseEntity<Map<String, Object>> executeDynamicTool(
|
public ResponseEntity<Map<String, Object>> executeDynamicTool(
|
||||||
@org.springframework.web.bind.annotation.RequestHeader(value = "X-Request-Id", required = false) String headerRequestId,
|
@RequestHeader(value = "X-Request-Id", required = false) String headerRequestId,
|
||||||
@RequestBody(required = false) Map<String, Object> payload) {
|
@RequestBody(required = false) Map<String, Object> payload) {
|
||||||
|
|
||||||
String finalRequestId = headerRequestId != null ? headerRequestId : (payload != null && payload.get("id") != null ? String.valueOf(payload.get("id")) : null);
|
String finalRequestId = headerRequestId != null ? headerRequestId : (payload != null && payload.get("id") != null ? String.valueOf(payload.get("id")) : null);
|
||||||
@@ -139,7 +124,7 @@ public class BusinessToolController {
|
|||||||
error.put("jsonrpc", "2.0");
|
error.put("jsonrpc", "2.0");
|
||||||
error.put("error", errorBody);
|
error.put("error", errorBody);
|
||||||
error.put("id", payload != null ? payload.get("id") : null);
|
error.put("id", payload != null ? payload.get("id") : null);
|
||||||
return org.springframework.http.ResponseEntity.status(404).body(error);
|
return ResponseEntity.status(404).body(error);
|
||||||
}
|
}
|
||||||
// (기존 차단 로직 제거됨)
|
// (기존 차단 로직 제거됨)
|
||||||
|
|
||||||
@@ -173,7 +158,7 @@ public class BusinessToolController {
|
|||||||
error.put("jsonrpc", "2.0");
|
error.put("jsonrpc", "2.0");
|
||||||
error.put("error", errorBody);
|
error.put("error", errorBody);
|
||||||
error.put("id", payload != null ? payload.get("id") : null);
|
error.put("id", payload != null ? payload.get("id") : null);
|
||||||
return org.springframework.http.ResponseEntity.status(422).body(error);
|
return ResponseEntity.status(422).body(error);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("[Tool] 스키마 검증 중 오류 발생: {}", e.getMessage());
|
log.error("[Tool] 스키마 검증 중 오류 발생: {}", e.getMessage());
|
||||||
@@ -243,7 +228,7 @@ public class BusinessToolController {
|
|||||||
}
|
}
|
||||||
resultPayload.put("original_size", originalSize);
|
resultPayload.put("original_size", originalSize);
|
||||||
|
|
||||||
Map<String, Object> rpcResponse = new java.util.LinkedHashMap<>(); // 순서 보장을 위해 LinkedHashMap 사용
|
Map<String, Object> rpcResponse = new LinkedHashMap<>(); // 순서 보장을 위해 LinkedHashMap 사용
|
||||||
rpcResponse.put("jsonrpc", "2.0");
|
rpcResponse.put("jsonrpc", "2.0");
|
||||||
rpcResponse.put("result", resultPayload);
|
rpcResponse.put("result", resultPayload);
|
||||||
rpcResponse.put("id", payload != null ? payload.get("id") : null);
|
rpcResponse.put("id", payload != null ? payload.get("id") : null);
|
||||||
@@ -255,7 +240,7 @@ public class BusinessToolController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return org.springframework.http.ResponseEntity.ok(rpcResponse);
|
return ResponseEntity.ok(rpcResponse);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("[Tool] 리플렉션 실행 중 예외 발생: {}", e.getMessage());
|
log.error("[Tool] 리플렉션 실행 중 예외 발생: {}", e.getMessage());
|
||||||
@@ -272,7 +257,7 @@ public class BusinessToolController {
|
|||||||
error.put("jsonrpc", "2.0");
|
error.put("jsonrpc", "2.0");
|
||||||
error.put("error", errorBody);
|
error.put("error", errorBody);
|
||||||
error.put("id", payload != null ? payload.get("id") : null);
|
error.put("id", payload != null ? payload.get("id") : null);
|
||||||
return org.springframework.http.ResponseEntity.status(502).body(error);
|
return ResponseEntity.status(502).body(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,47 +1,33 @@
|
|||||||
package io.shinhanlife.axhub.biz.mcp.tool.service;
|
package io.shinhanlife.axhub.biz.mcp.tool.service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction;
|
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction;
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpTool;
|
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpTool;
|
||||||
|
import io.shinhanlife.axhub.biz.mcp.tool.config.McpProperties;
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.dto.ToolMetadata;
|
import io.shinhanlife.axhub.biz.mcp.tool.dto.ToolMetadata;
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.util.JsonSchemaGenerator;
|
import io.shinhanlife.axhub.biz.mcp.tool.util.JsonSchemaGenerator;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.web.client.RestClient;
|
|
||||||
|
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.config.McpProperties;
|
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.springframework.util.ClassUtils;
|
import java.util.UUID;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.aop.support.AopUtils;
|
import org.springframework.aop.support.AopUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.web.client.RestClient;
|
||||||
|
|
||||||
/**
|
|
||||||
* @package io.shinhanlife.axhub.biz.mcp.tool.service
|
|
||||||
* @className ToolRegistryHeartbeatSender
|
|
||||||
* @description AX HUB 시스템 처리 클래스
|
|
||||||
* @author 김형식
|
|
||||||
* @create 2026.09.01
|
|
||||||
* <pre>
|
|
||||||
* ---------- 개정이력 ----------
|
|
||||||
* 수정일 수정자 수정내용
|
|
||||||
* ---------- -------- ---------------------------
|
|
||||||
* 2026.09.01 김형식 최초생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -92,7 +78,7 @@ public class ToolRegistryHeartbeatSender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ToolMetadata meta = new ToolMetadata();
|
ToolMetadata meta = new ToolMetadata();
|
||||||
meta.setUid(java.util.UUID.nameUUIDFromBytes(subToolName.getBytes()).toString());
|
meta.setUid(UUID.nameUUIDFromBytes(subToolName.getBytes()).toString());
|
||||||
meta.setDisplayName(baseName);
|
meta.setDisplayName(baseName);
|
||||||
meta.setName(subToolName);
|
meta.setName(subToolName);
|
||||||
meta.setSemver("1.0.0");
|
meta.setSemver("1.0.0");
|
||||||
@@ -141,7 +127,7 @@ public class ToolRegistryHeartbeatSender {
|
|||||||
|
|
||||||
for (ToolMetadata tool : registeredTools) {
|
for (ToolMetadata tool : registeredTools) {
|
||||||
try {
|
try {
|
||||||
org.springframework.http.ResponseEntity<String> response = restClient.post()
|
ResponseEntity<String> response = restClient.post()
|
||||||
.uri(gatewayUrl + "/mcp/api/v1/registry/heartbeat")
|
.uri(gatewayUrl + "/mcp/api/v1/registry/heartbeat")
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
|
|
||||||
|
|||||||
@@ -3,22 +3,9 @@ package io.shinhanlife.axhub.biz.mcp.tool.util;
|
|||||||
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpParameter;
|
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpParameter;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
|
||||||
* @package io.shinhanlife.axhub.biz.mcp.tool.util
|
|
||||||
* @className JsonSchemaGenerator
|
|
||||||
* @description AX HUB 시스템 처리 클래스
|
|
||||||
* @author 김형식
|
|
||||||
* @create 2026.09.01
|
|
||||||
* <pre>
|
|
||||||
* ---------- 개정이력 ----------
|
|
||||||
* 수정일 수정자 수정내용
|
|
||||||
* ---------- -------- ---------------------------
|
|
||||||
* 2026.09.01 김형식 최초생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
public class JsonSchemaGenerator {
|
public class JsonSchemaGenerator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,7 +41,7 @@ public class JsonSchemaGenerator {
|
|||||||
if (clazz == Double.class || clazz == double.class) return "number";
|
if (clazz == Double.class || clazz == double.class) return "number";
|
||||||
if (clazz == Float.class || clazz == float.class) return "number";
|
if (clazz == Float.class || clazz == float.class) return "number";
|
||||||
if (clazz == Boolean.class || clazz == boolean.class) return "boolean";
|
if (clazz == Boolean.class || clazz == boolean.class) return "boolean";
|
||||||
if (java.util.List.class.isAssignableFrom(clazz)) return "array";
|
if (List.class.isAssignableFrom(clazz)) return "array";
|
||||||
return "object";
|
return "object";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,24 +2,11 @@ package io.shinhanlife.axhub.biz.mcp.tool.email;
|
|||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
|
||||||
/**
|
|
||||||
* @package io.shinhanlife.axhub.biz.mcp.tool.email
|
|
||||||
* @className AxHubToolEmailApplication
|
|
||||||
* @description AX HUB 시스템 처리 클래스
|
|
||||||
* @author 김형식
|
|
||||||
* @create 2026.09.01
|
|
||||||
* <pre>
|
|
||||||
* ---------- 개정이력 ----------
|
|
||||||
* 수정일 수정자 수정내용
|
|
||||||
* ---------- -------- ---------------------------
|
|
||||||
* 2026.09.01 김형식 최초생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
||||||
@org.springframework.boot.context.properties.ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
@ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
public class AxHubToolEmailApplication {
|
public class AxHubToolEmailApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import lombok.Data;
|
|||||||
* 2026.07.13 root 최초생성
|
* 2026.07.13 root 최초생성
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/1
|
||||||
@Data
|
@Data
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
public class SearchDetailHrReq {
|
public class SearchDetailHrReq {
|
||||||
|
|||||||
@@ -2,24 +2,11 @@ package io.shinhanlife.axhub.biz.mcp.tool.hr;
|
|||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
|
||||||
/**
|
|
||||||
* @package io.shinhanlife.axhub.biz.mcp.tool.hr
|
|
||||||
* @className HrToolApplication
|
|
||||||
* @description AX HUB 시스템 처리 클래스
|
|
||||||
* @author root
|
|
||||||
* @create 2026.07.13
|
|
||||||
* <pre>
|
|
||||||
* ---------- 개정이력 ----------
|
|
||||||
* 수정일 수정자 수정내용
|
|
||||||
* ---------- -------- ---------------------------
|
|
||||||
* 2026.07.13 root 최초생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
||||||
@org.springframework.boot.context.properties.ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
@ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
public class HrToolApplication {
|
public class HrToolApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
@@ -2,24 +2,11 @@ package io.shinhanlife.axhub.biz.mcp.tool.other;
|
|||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
|
||||||
/**
|
|
||||||
* @package io.shinhanlife.axhub.biz.mcp.tool.other
|
|
||||||
* @className AxHubToolOtherApplication
|
|
||||||
* @description AX HUB 시스템 처리 클래스
|
|
||||||
* @author 김형식
|
|
||||||
* @create 2026.09.01
|
|
||||||
* <pre>
|
|
||||||
* ---------- 개정이력 ----------
|
|
||||||
* 수정일 수정자 수정내용
|
|
||||||
* ---------- -------- ---------------------------
|
|
||||||
* 2026.09.01 김형식 최초생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
||||||
@org.springframework.boot.context.properties.ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
@ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
public class AxHubToolOtherApplication {
|
public class AxHubToolOtherApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ package io.shinhanlife.axhub.biz.mcp.tool.service;
|
|||||||
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction;
|
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction;
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpTool;
|
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpTool;
|
||||||
import io.shinhanlife.axhub.biz.mcp.tool.dto.TemplateDownloadReq;
|
import io.shinhanlife.axhub.biz.mcp.tool.dto.TemplateDownloadReq;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@@ -42,16 +44,16 @@ public class TemplateUtilityService extends AbstractMcpToolService {
|
|||||||
String fileName = "sample_" + templateId + ".xlsx";
|
String fileName = "sample_" + templateId + ".xlsx";
|
||||||
String downloadUrl = "https://axhub-file-server.shinhanlife.io/downloads/" + fileName;
|
String downloadUrl = "https://axhub-file-server.shinhanlife.io/downloads/" + fileName;
|
||||||
|
|
||||||
Map<String, Object> result = new java.util.HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
result.put("status", "success");
|
result.put("status", "success");
|
||||||
|
|
||||||
Map<String, Object> contract = new java.util.HashMap<>();
|
Map<String, Object> contract = new HashMap<>();
|
||||||
contract.put("fileName", fileName);
|
contract.put("fileName", fileName);
|
||||||
contract.put("downloadUrl", downloadUrl);
|
contract.put("downloadUrl", downloadUrl);
|
||||||
contract.put("message", "다운로드 링크가 성공적으로 생성되었습니다. AI는 이 링크를 마크다운 형식으로 사용자에게 전달해야 합니다.");
|
contract.put("message", "다운로드 링크가 성공적으로 생성되었습니다. AI는 이 링크를 마크다운 형식으로 사용자에게 전달해야 합니다.");
|
||||||
contract.put("status", "success");
|
contract.put("status", "success");
|
||||||
|
|
||||||
result.put("contracts", java.util.Collections.singletonList(contract));
|
result.put("contracts", Collections.singletonList(contract));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ package io.shinhanlife.axhub.biz.mcp.tool.payment;
|
|||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
|
||||||
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
||||||
@org.springframework.boot.context.properties.ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
@ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
public class PaymentToolApplication {
|
public class PaymentToolApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
@@ -2,24 +2,11 @@ package io.shinhanlife.axhub.biz.mcp.tool.sms;
|
|||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
|
||||||
/**
|
|
||||||
* @package io.shinhanlife.axhub.biz.mcp.tool.sms
|
|
||||||
* @className AxHubToolSmsApplication
|
|
||||||
* @description AX HUB 시스템 처리 클래스
|
|
||||||
* @author 김형식
|
|
||||||
* @create 2026.09.01
|
|
||||||
* <pre>
|
|
||||||
* ---------- 개정이력 ----------
|
|
||||||
* 수정일 수정자 수정내용
|
|
||||||
* ---------- -------- ---------------------------
|
|
||||||
* 2026.09.01 김형식 최초생성
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
||||||
@org.springframework.boot.context.properties.ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
@ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.axhub.biz.mcp.tool", "io.shinhanlife.axhub.biz.mcp.adapter", "io.shinhanlife.axhub.common.mcp", "io.shinhanlife.axhub.common.config"})
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
public class AxHubToolSmsApplication {
|
public class AxHubToolSmsApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
106
fix_imports.py
Normal file
106
fix_imports.py
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
root_dir = "."
|
||||||
|
target_ext = ".java"
|
||||||
|
|
||||||
|
# Regex to find fully qualified class names
|
||||||
|
fqcn_pattern = re.compile(r'\b(((?:java\.util|java\.time|java\.io|java\.math|java\.net)\.[a-z0-9.]*?([A-Z]\w+))|(org\.springframework\.[a-z0-9.]*?([A-Z]\w+))|(io\.shinhanlife\.[a-z0-9.]*?([A-Z]\w+)))\b')
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
for subdir, dirs, files in os.walk(root_dir):
|
||||||
|
if '.git' in dirs: dirs.remove('.git')
|
||||||
|
if 'build' in dirs: dirs.remove('build')
|
||||||
|
if '.gradle' in dirs: dirs.remove('.gradle')
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
if file.endswith(target_ext):
|
||||||
|
filepath = os.path.join(subdir, file)
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r', encoding='utf-8') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
lines = content.split('\n')
|
||||||
|
new_imports = set()
|
||||||
|
new_lines = []
|
||||||
|
modified = False
|
||||||
|
|
||||||
|
in_block_comment = False
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
stripped = line.strip()
|
||||||
|
|
||||||
|
if stripped.startswith('/*'):
|
||||||
|
in_block_comment = True
|
||||||
|
|
||||||
|
is_comment = in_block_comment or stripped.startswith('//') or stripped.startswith('*')
|
||||||
|
|
||||||
|
if stripped.endswith('*/'):
|
||||||
|
in_block_comment = False
|
||||||
|
|
||||||
|
if stripped.startswith('import ') or stripped.startswith('package '):
|
||||||
|
new_lines.append(line)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if is_comment:
|
||||||
|
new_lines.append(line)
|
||||||
|
continue
|
||||||
|
|
||||||
|
def repl(match):
|
||||||
|
fqcn = match.group(1)
|
||||||
|
# Extract the simple class name
|
||||||
|
class_name = match.group(3) or match.group(5) or match.group(7)
|
||||||
|
|
||||||
|
if class_name:
|
||||||
|
new_imports.add(f"import {fqcn};")
|
||||||
|
return class_name
|
||||||
|
return fqcn
|
||||||
|
|
||||||
|
new_line = fqcn_pattern.sub(repl, line)
|
||||||
|
if new_line != line:
|
||||||
|
modified = True
|
||||||
|
new_lines.append(new_line)
|
||||||
|
|
||||||
|
if modified:
|
||||||
|
existing_imports = set()
|
||||||
|
insert_idx = 0
|
||||||
|
package_line = ""
|
||||||
|
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
stripped = line.strip()
|
||||||
|
if stripped.startswith('package '):
|
||||||
|
package_line = line
|
||||||
|
elif stripped.startswith('import '):
|
||||||
|
existing_imports.add(stripped)
|
||||||
|
elif stripped == '' or stripped.startswith('//') or stripped.startswith('/*') or stripped.startswith('*'):
|
||||||
|
continue
|
||||||
|
elif package_line and not stripped.startswith('import '):
|
||||||
|
insert_idx = i
|
||||||
|
break
|
||||||
|
|
||||||
|
all_imports = existing_imports.union(new_imports)
|
||||||
|
sorted_imports = sorted(list(all_imports))
|
||||||
|
|
||||||
|
res_lines = []
|
||||||
|
if package_line:
|
||||||
|
res_lines.append(package_line)
|
||||||
|
res_lines.append('')
|
||||||
|
|
||||||
|
for imp in sorted_imports:
|
||||||
|
res_lines.append(imp)
|
||||||
|
|
||||||
|
res_lines.append('')
|
||||||
|
|
||||||
|
res_lines.extend(new_lines[insert_idx:])
|
||||||
|
|
||||||
|
new_content = '\n'.join(res_lines)
|
||||||
|
|
||||||
|
with open(filepath, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(new_content)
|
||||||
|
print(f"Fixed imports in: {filepath}")
|
||||||
|
count += 1
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error processing {filepath}: {e}")
|
||||||
|
|
||||||
|
print(f"\nTotal files fixed: {count}")
|
||||||
Reference in New Issue
Block a user