forked from kimhyungsik/ax_hub_mcp_tool
refactor: relocate ToolMetadata, AbstractMcpToolUseCase, and LocalToolScanner
This commit is contained in:
@@ -18,8 +18,8 @@ package io.shinhanlife.dap.lib.manifest;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.shinhanlife.dap.lib.config.McpProperties;
|
import io.shinhanlife.dap.lib.config.McpProperties;
|
||||||
import io.shinhanlife.dap.lib.dto.ToolMetadata;
|
import io.shinhanlife.dap.mcc.dto.ToolMetadata;
|
||||||
import io.shinhanlife.dap.lib.usecase.LocalToolScanner;
|
import io.shinhanlife.dap.lib.mcp.LocalToolScanner;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package io.shinhanlife.dap.lib.usecase;
|
package io.shinhanlife.dap.lib.mcp;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,7 +19,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import io.shinhanlife.dap.lib.annotation.McpFunction;
|
import io.shinhanlife.dap.lib.annotation.McpFunction;
|
||||||
import io.shinhanlife.dap.lib.annotation.McpTool;
|
import io.shinhanlife.dap.lib.annotation.McpTool;
|
||||||
import io.shinhanlife.dap.lib.config.McpProperties;
|
import io.shinhanlife.dap.lib.config.McpProperties;
|
||||||
import io.shinhanlife.dap.lib.dto.ToolMetadata;
|
import io.shinhanlife.dap.mcc.dto.ToolMetadata;
|
||||||
import io.shinhanlife.dap.lib.util.ToolSchemaResolver;
|
import io.shinhanlife.dap.lib.util.ToolSchemaResolver;
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@@ -20,9 +20,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import io.modelcontextprotocol.server.McpServerFeatures;
|
import io.modelcontextprotocol.server.McpServerFeatures;
|
||||||
import io.modelcontextprotocol.server.McpSyncServer;
|
import io.modelcontextprotocol.server.McpSyncServer;
|
||||||
import io.modelcontextprotocol.spec.McpSchema;
|
import io.modelcontextprotocol.spec.McpSchema;
|
||||||
import io.shinhanlife.dap.lib.dto.ToolMetadata;
|
import io.shinhanlife.dap.mcc.dto.ToolMetadata;
|
||||||
import io.shinhanlife.dap.lib.presentation.BusinessToolController;
|
import io.shinhanlife.dap.lib.presentation.BusinessToolController;
|
||||||
import io.shinhanlife.dap.lib.usecase.LocalToolScanner;
|
import io.shinhanlife.dap.lib.mcp.LocalToolScanner;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ import io.shinhanlife.dap.lib.validation.ToolArgumentSchemaValidator;
|
|||||||
import io.shinhanlife.dap.lib.annotation.McpFunction;
|
import io.shinhanlife.dap.lib.annotation.McpFunction;
|
||||||
import io.shinhanlife.dap.lib.annotation.McpTool;
|
import io.shinhanlife.dap.lib.annotation.McpTool;
|
||||||
import io.shinhanlife.dap.lib.config.McpProperties;
|
import io.shinhanlife.dap.lib.config.McpProperties;
|
||||||
import io.shinhanlife.dap.lib.dto.ToolMetadata;
|
import io.shinhanlife.dap.mcc.dto.ToolMetadata;
|
||||||
import io.shinhanlife.dap.lib.usecase.LocalToolScanner;
|
import io.shinhanlife.dap.lib.mcp.LocalToolScanner;
|
||||||
import io.shinhanlife.dap.lib.util.ToolSchemaResolver;
|
import io.shinhanlife.dap.lib.util.ToolSchemaResolver;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package io.shinhanlife.dap.lib.dto;
|
package io.shinhanlife.dap.mcc.dto;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
package io.shinhanlife.dap.mcc.presentation;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package io.shinhanlife.dap.mcc.presentation
|
||||||
|
* @className BusinessToolController
|
||||||
|
* @description AX HUB ??戮?츩??嶺뚳퐣瑗????????
|
||||||
|
* @author 0986406
|
||||||
|
* @create 2026.09.01
|
||||||
|
* <pre>
|
||||||
|
* ---------- ?띠룇裕??????----------
|
||||||
|
* ??瑜곸젧?? ??瑜곸젧?? ??瑜곸젧??怨몃뮔
|
||||||
|
* ---------- -------- ---------------------------
|
||||||
|
* 2026.09.01 0986406 嶺뚣끉裕???諛댁뎽
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.networknt.schema.Error;
|
||||||
|
import io.shinhanlife.dap.lib.validation.ToolArgumentSchemaValidator;
|
||||||
|
import io.shinhanlife.dap.lib.annotation.McpFunction;
|
||||||
|
import io.shinhanlife.dap.lib.annotation.McpTool;
|
||||||
|
import io.shinhanlife.dap.lib.config.McpProperties;
|
||||||
|
import io.shinhanlife.dap.mcc.dto.ToolMetadata;
|
||||||
|
import io.shinhanlife.dap.lib.mcp.LocalToolScanner;
|
||||||
|
import io.shinhanlife.dap.lib.util.ToolSchemaResolver;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
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 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;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class BusinessToolController {
|
||||||
|
|
||||||
|
private final ApplicationContext applicationContext;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
private final McpProperties mcpProperties;
|
||||||
|
private final LocalToolScanner localToolScanner;
|
||||||
|
private final ToolArgumentSchemaValidator toolArgumentSchemaValidator;
|
||||||
|
|
||||||
|
private final ToolSchemaResolver toolSchemaResolver;
|
||||||
|
// ???? ?브퀗?????β돦裕뉛쭚?Tool 嶺뚮ㅄ維뽨빳???븐뼔援?????
|
||||||
|
@GetMapping("/mcp/api/v1/tools/local")
|
||||||
|
public List<ToolMetadata> getLocalTools() {
|
||||||
|
return localToolScanner.getAllScannedTools();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ??戮?빢 REST ?リ옇?↑????됱쓤 ??源녿뮡????븐뼔援?????
|
||||||
|
@PostMapping("/mcp/{name}")
|
||||||
|
public ResponseEntity<?> executeDynamicTool(
|
||||||
|
@PathVariable("name") String functionName,
|
||||||
|
@RequestHeader(value = "X-Request-Id", required = false) String headerRequestId,
|
||||||
|
@RequestHeader(value = "trace-id", required = false) String traceId,
|
||||||
|
@RequestHeader(value = "request-id", required = false) String requestId,
|
||||||
|
@RequestHeader(value = "employee-id", required = false) String encryptedEmployeeId,
|
||||||
|
@RequestBody(required = false) Map<String, Object> arguments) {
|
||||||
|
|
||||||
|
String finalRequestId = headerRequestId;
|
||||||
|
|
||||||
|
log.info(" [Tool] IN - trace-id: {}, request-id: {}", traceId, requestId);
|
||||||
|
log.info(" [Tool] ???됱쓤 ?????덈뺄 ??븐슙????琉용뼁 (??貫?양춯?: {}", functionName);
|
||||||
|
if (arguments != null) {
|
||||||
|
try {
|
||||||
|
log.info(" [Tool] ?筌뤾쑵?????逾ф쾬?롮구?? {}", objectMapper.writeValueAsString(arguments));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info(" [Tool] ?筌뤾쑵?????逾ф쾬?롮구?? {}", arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Object targetBean = null;
|
||||||
|
Method targetMethod = null;
|
||||||
|
McpFunction targetFunctionAnnotation = null;
|
||||||
|
|
||||||
|
// McpTool ???????逾???リ옇?↑??브퀗???뱀쾸? ?熬곣뫁夷????쒖굣?節놁뿉??熬곣뫁逾???????깅さ亦껋깢??? ?熬곣뫕??????????щ뤂????@McpFunction??嶺뚢돦堉????덈펲.
|
||||||
|
Map<String, Object> allBeans = applicationContext.getBeansOfType(Object.class);
|
||||||
|
outerLoop:
|
||||||
|
for (Object bean : allBeans.values()) {
|
||||||
|
Class<?> targetClass = AopUtils.getTargetClass(bean);
|
||||||
|
for (Method targetMethodOfClass : targetClass.getDeclaredMethods()) {
|
||||||
|
McpFunction mcpFunc = AnnotationUtils.findAnnotation(targetMethodOfClass, McpFunction.class);
|
||||||
|
if (mcpFunc != null) {
|
||||||
|
String baseName = mcpFunc.name();
|
||||||
|
String expectedName = mcpProperties.getNamespace() != null && !mcpProperties.getNamespace().isEmpty()
|
||||||
|
? mcpProperties.getNamespace() + "_" + baseName
|
||||||
|
: baseName;
|
||||||
|
|
||||||
|
if (expectedName.equals(functionName) || baseName.equals(functionName)) {
|
||||||
|
targetBean = bean;
|
||||||
|
try {
|
||||||
|
targetMethod = bean.getClass().getMethod(targetMethodOfClass.getName(), targetMethodOfClass.getParameterTypes());
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
targetMethod = targetMethodOfClass;
|
||||||
|
}
|
||||||
|
targetFunctionAnnotation = mcpFunc;
|
||||||
|
break outerLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetBean == null || targetMethod == null) {
|
||||||
|
List<String> availableFunctions = new ArrayList<>();
|
||||||
|
for (Object bean : allBeans.values()) {
|
||||||
|
Class<?> targetCls = AopUtils.getTargetClass(bean);
|
||||||
|
for (Method m : targetCls.getDeclaredMethods()) {
|
||||||
|
McpFunction func = AnnotationUtils.findAnnotation(m, McpFunction.class);
|
||||||
|
if (func != null) {
|
||||||
|
String baseName = func.name();
|
||||||
|
String expName = mcpProperties.getNamespace() != null && !mcpProperties.getNamespace().isEmpty()
|
||||||
|
? mcpProperties.getNamespace() + "_" + baseName : baseName;
|
||||||
|
availableFunctions.add(expName + " (in " + targetCls.getSimpleName() + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.error("[Tool] ???덈뺄????貫??Method)??嶺뚢돦堉??????怨룸????덈펲: {}. ?熬곣뫗?????노뼌????嶺뚮∥?꾥땻??嶺뚮ㅄ維뽨빳? {}", functionName, availableFunctions);
|
||||||
|
Map<String, Object> errorDetails = new HashMap<>();
|
||||||
|
errorDetails.put("status", "404");
|
||||||
|
Map<String, Object> errorBody = new HashMap<>();
|
||||||
|
errorBody.put("code", "TOOL_NOT_FOUND");
|
||||||
|
errorBody.put("message", "???덈뺄????貫???嶺뚢돦堉??????怨룸????덈펲: " + functionName);
|
||||||
|
errorBody.put("details", errorDetails);
|
||||||
|
if (finalRequestId != null) errorBody.put("request_id", finalRequestId);
|
||||||
|
|
||||||
|
return ResponseEntity.status(404).body(errorBody);
|
||||||
|
}
|
||||||
|
// (?リ옇???嶺뚢뼰維???β돦裕뉐퐲???蹂ㅽ깴??
|
||||||
|
|
||||||
|
// 2. ???逾ф쾬?롮구????ル쪇????롪틵?嶺?(JSON Schema)
|
||||||
|
if (targetMethod.getParameterCount() > 0) {
|
||||||
|
Class<?> paramType = targetMethod.getParameterTypes()[0];
|
||||||
|
if (!Map.class.isAssignableFrom(paramType)) {
|
||||||
|
try {
|
||||||
|
Map<String, Object> inputSchema = toolSchemaResolver.resolve(targetFunctionAnnotation, paramType);
|
||||||
|
List<Error> errors = toolArgumentSchemaValidator.validate(inputSchema, arguments);
|
||||||
|
if (!errors.isEmpty()) {
|
||||||
|
log.error("[Tool] ???逾ф쾬?롮구????ル쪇????롪틵?嶺????덉넮: {}", errors);
|
||||||
|
List<String> errorMessages = new ArrayList<>();
|
||||||
|
for (Error validationError : errors) {
|
||||||
|
errorMessages.add(validationError.getMessage());
|
||||||
|
}
|
||||||
|
Map<String, Object> errorDetails = new HashMap<>();
|
||||||
|
errorDetails.put("status", "422");
|
||||||
|
Map<String, Object> errorBody = new HashMap<>();
|
||||||
|
errorBody.put("code", "INVALID_PARAM");
|
||||||
|
errorBody.put("message", "???逾ф쾬?롮구????ル쪇????롪틵?嶺????덉넮");
|
||||||
|
errorBody.put("details", errorDetails);
|
||||||
|
if (finalRequestId != null) errorBody.put("request_id", finalRequestId);
|
||||||
|
|
||||||
|
return ResponseEntity.status(422).body(errorBody);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[Tool] ???꾪뀞嶺??롪틵?嶺?繞????댁쾼 ?꾩룇裕뉑틦? {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("[Tool] ?洹먮뿫???源끒?嶺뚯쉳??????덈뺄 -> Method: {}", targetMethod.getName());
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 3. DTO ???逾ф쾬?롮구?????吏?嶺뚮씞?뗩뇡?(Map -> DTO)
|
||||||
|
Object invokeArgument = arguments;
|
||||||
|
if (targetMethod.getParameterCount() > 0 && arguments != null) {
|
||||||
|
Class<?> paramType = targetMethod.getParameterTypes()[0];
|
||||||
|
if (!Map.class.isAssignableFrom(paramType)) {
|
||||||
|
invokeArgument = objectMapper.convertValue(arguments, paramType);
|
||||||
|
log.info("[Tool] DTO ???吏?嶺뚮씞?뗩뇡??繹먭퍓沅? {}", paramType.getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
Object methodResult = null;
|
||||||
|
if (targetMethod.getParameterCount() == 0) {
|
||||||
|
methodResult = targetMethod.invoke(targetBean);
|
||||||
|
} else {
|
||||||
|
methodResult = targetMethod.invoke(targetBean, invokeArgument);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> outputSchema = toolSchemaResolver.resolveOutput(targetFunctionAnnotation, targetMethod.getReturnType());
|
||||||
|
if (!outputSchema.isEmpty()) {
|
||||||
|
List<Error> outputErrors = toolArgumentSchemaValidator.validateValue(outputSchema, methodResult);
|
||||||
|
if (!outputErrors.isEmpty()) {
|
||||||
|
log.error("[Tool] Output schema validation failed. tool={}, errors={}",
|
||||||
|
functionName, outputErrors);
|
||||||
|
Map<String, Object> errorBody = new HashMap<>();
|
||||||
|
errorBody.put("code", "INVALID_TOOL_RESPONSE");
|
||||||
|
errorBody.put("message", "Tool response does not match its output schema");
|
||||||
|
if (finalRequestId != null) {
|
||||||
|
errorBody.put("request_id", finalRequestId);
|
||||||
|
}
|
||||||
|
return ResponseEntity.internalServerError().body(errorBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long elapsed = System.currentTimeMillis() - startTime;
|
||||||
|
|
||||||
|
// 5. ?롪퍒????꾩룇瑗??(??戮?빢 REST ??얜Ŧ堉?
|
||||||
|
try {
|
||||||
|
log.info("[Tool Execution] Output Schema Result: {}", objectMapper.writeValueAsString(methodResult));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("[Tool Execution] Output Schema Result: {}", methodResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info(" [Tool] OUT - trace-id: {}, request-id: {}", traceId, requestId);
|
||||||
|
|
||||||
|
ResponseEntity.BodyBuilder responseBuilder = ResponseEntity.ok();
|
||||||
|
if (traceId != null) responseBuilder.header("trace-id", traceId);
|
||||||
|
if (requestId != null) responseBuilder.header("request-id", requestId);
|
||||||
|
|
||||||
|
return responseBuilder.body(methodResult);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[Tool] ?洹먮뿫???源끒????덈뺄 繞????깅뇶 ?꾩룇裕뉑틦? {}", e.getMessage());
|
||||||
|
Map<String, Object> errorDetails = new HashMap<>();
|
||||||
|
errorDetails.put("status", "500");
|
||||||
|
Map<String, Object> errorBody = new HashMap<>();
|
||||||
|
errorBody.put("code", "TOOL_ERROR");
|
||||||
|
errorBody.put("message", "Tool execution failed");
|
||||||
|
errorDetails.clear(); // Hide details for upstream errors
|
||||||
|
errorBody.put("details", errorDetails);
|
||||||
|
if (finalRequestId != null) errorBody.put("request_id", finalRequestId);
|
||||||
|
|
||||||
|
return ResponseEntity.status(502).body(errorBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package io.shinhanlife.dap.mcc.presentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package io.shinhanlife.dap.mcc.presentation
|
||||||
|
* @className ToolManifestController
|
||||||
|
* @description AX HUB ?쒖뒪??泥섎━ ?대옒??
|
||||||
|
* @author 0986406
|
||||||
|
* @create 2026.09.01
|
||||||
|
* <pre>
|
||||||
|
* ---------- 媛쒖젙?대젰 ----------
|
||||||
|
* ?섏젙?? ?섏젙?? ?섏젙?댁슜
|
||||||
|
* ---------- -------- ---------------------------
|
||||||
|
* 2026.09.01 0986406 理쒖큹?앹꽦
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import io.shinhanlife.dap.lib.manifest.ToolManifestResponse;
|
||||||
|
import io.shinhanlife.dap.lib.manifest.ToolManifestService;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/** Read-only Tool Service manifest endpoint for MCP background discovery. */
|
||||||
|
@RestController
|
||||||
|
public class ToolManifestController {
|
||||||
|
|
||||||
|
private final ToolManifestService toolManifestService;
|
||||||
|
|
||||||
|
public ToolManifestController(ToolManifestService toolManifestService) {
|
||||||
|
this.toolManifestService = toolManifestService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/tool-manifest", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
public ResponseEntity<ToolManifestResponse> getManifest(
|
||||||
|
@RequestHeader(value = HttpHeaders.IF_NONE_MATCH, required = false) String ifNoneMatch) {
|
||||||
|
ToolManifestResponse manifest = toolManifestService.currentManifest();
|
||||||
|
String eTag = '"' + manifest.revision() + '"';
|
||||||
|
if (eTag.equals(ifNoneMatch)) {
|
||||||
|
return ResponseEntity.status(304).eTag(eTag).build();
|
||||||
|
}
|
||||||
|
return ResponseEntity.ok().eTag(eTag).body(manifest);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package io.shinhanlife.dap.lib.usecase;
|
package io.shinhanlife.dap.mcc.usecase;
|
||||||
|
|
||||||
import io.shinhanlife.dap.lib.adapter.connector.LegacyEimsConnector;
|
import io.shinhanlife.dap.lib.adapter.connector.LegacyEimsConnector;
|
||||||
import io.shinhanlife.dap.lib.adapter.util.PiiMaskingUtils;
|
import io.shinhanlife.dap.lib.adapter.util.PiiMaskingUtils;
|
||||||
@@ -22,7 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.shinhanlife.dap.lib.config.McpProperties;
|
import io.shinhanlife.dap.lib.config.McpProperties;
|
||||||
import io.shinhanlife.dap.lib.dto.ToolMetadata;
|
import io.shinhanlife.dap.mcc.dto.ToolMetadata;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import static org.mockito.Mockito.when;
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.modelcontextprotocol.server.McpSyncServer;
|
import io.modelcontextprotocol.server.McpSyncServer;
|
||||||
import io.shinhanlife.dap.lib.presentation.BusinessToolController;
|
import io.shinhanlife.dap.lib.presentation.BusinessToolController;
|
||||||
import io.shinhanlife.dap.lib.usecase.LocalToolScanner;
|
import io.shinhanlife.dap.lib.mcp.LocalToolScanner;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
|||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.BalanceUseCase;
|
import io.shinhanlife.dap.mcc.biz.cmm.usecase.BalanceUseCase;
|
||||||
import io.shinhanlife.dap.lib.usecase.AbstractMcpToolUseCase;
|
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.BalanceRequest;
|
import io.shinhanlife.dap.mcc.biz.cmm.dto.BalanceRequest;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
|||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.BillingProcessUseCase;
|
import io.shinhanlife.dap.mcc.biz.cmm.usecase.BillingProcessUseCase;
|
||||||
import io.shinhanlife.dap.lib.usecase.AbstractMcpToolUseCase;
|
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.BillingProcessRequest;
|
import io.shinhanlife.dap.mcc.biz.cmm.dto.BillingProcessRequest;
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.BillingStatusRequest;
|
import io.shinhanlife.dap.mcc.biz.cmm.dto.BillingStatusRequest;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
||||||
|
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.BondIssueUseCase;
|
import io.shinhanlife.dap.mcc.biz.cmm.usecase.BondIssueUseCase;
|
||||||
import io.shinhanlife.dap.lib.usecase.AbstractMcpToolUseCase;
|
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.BondCheckRequest;
|
import io.shinhanlife.dap.mcc.biz.cmm.dto.BondCheckRequest;
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.BondIssueRequest;
|
import io.shinhanlife.dap.mcc.biz.cmm.dto.BondIssueRequest;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
||||||
|
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.CommonUtilityUseCase;
|
import io.shinhanlife.dap.mcc.biz.cmm.usecase.CommonUtilityUseCase;
|
||||||
import io.shinhanlife.dap.lib.usecase.AbstractMcpToolUseCase;
|
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.LeaveCountRequest;
|
import io.shinhanlife.dap.mcc.biz.cmm.dto.LeaveCountRequest;
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.VacationRegisterRequest;
|
import io.shinhanlife.dap.mcc.biz.cmm.dto.VacationRegisterRequest;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
||||||
|
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.ContractInquiryUseCase;
|
import io.shinhanlife.dap.mcc.biz.cmm.usecase.ContractInquiryUseCase;
|
||||||
import io.shinhanlife.dap.lib.usecase.AbstractMcpToolUseCase;
|
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.ContractDetailRequest;
|
import io.shinhanlife.dap.mcc.biz.cmm.dto.ContractDetailRequest;
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.ContractStatusRequest;
|
import io.shinhanlife.dap.mcc.biz.cmm.dto.ContractStatusRequest;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
||||||
|
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.CustomerInfoUseCase;
|
import io.shinhanlife.dap.mcc.biz.cmm.usecase.CustomerInfoUseCase;
|
||||||
import io.shinhanlife.dap.lib.usecase.AbstractMcpToolUseCase;
|
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.CustomerDetailRequest;
|
import io.shinhanlife.dap.mcc.biz.cmm.dto.CustomerDetailRequest;
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.CustomerGradeRequest;
|
import io.shinhanlife.dap.mcc.biz.cmm.dto.CustomerGradeRequest;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
||||||
|
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.TemplateUtilityUseCase;
|
import io.shinhanlife.dap.mcc.biz.cmm.usecase.TemplateUtilityUseCase;
|
||||||
import io.shinhanlife.dap.lib.usecase.AbstractMcpToolUseCase;
|
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.TemplateDownloadRequest;
|
import io.shinhanlife.dap.mcc.biz.cmm.dto.TemplateDownloadRequest;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package io.shinhanlife.dap.mcc.biz.smp.usecase.impl;
|
|||||||
import io.shinhanlife.dap.mcc.biz.smp.dto.DailyQuoteRequest;
|
import io.shinhanlife.dap.mcc.biz.smp.dto.DailyQuoteRequest;
|
||||||
import io.shinhanlife.dap.mcc.biz.smp.dto.DailyQuoteResponse;
|
import io.shinhanlife.dap.mcc.biz.smp.dto.DailyQuoteResponse;
|
||||||
import io.shinhanlife.dap.mcc.biz.smp.usecase.DailyQuoteToolUseCase;
|
import io.shinhanlife.dap.mcc.biz.smp.usecase.DailyQuoteToolUseCase;
|
||||||
import io.shinhanlife.dap.lib.usecase.AbstractMcpToolUseCase;
|
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package io.shinhanlife.dap.mcc.biz.smp.usecase.impl;
|
|||||||
import io.shinhanlife.dap.mcc.biz.smp.dto.ExchangeRateRequest;
|
import io.shinhanlife.dap.mcc.biz.smp.dto.ExchangeRateRequest;
|
||||||
import io.shinhanlife.dap.mcc.biz.smp.dto.ExchangeRateResponse;
|
import io.shinhanlife.dap.mcc.biz.smp.dto.ExchangeRateResponse;
|
||||||
import io.shinhanlife.dap.mcc.biz.smp.usecase.ExchangeRateToolUseCase;
|
import io.shinhanlife.dap.mcc.biz.smp.usecase.ExchangeRateToolUseCase;
|
||||||
import io.shinhanlife.dap.lib.usecase.AbstractMcpToolUseCase;
|
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.client.RestClient;
|
import org.springframework.web.client.RestClient;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package io.shinhanlife.dap.mcc.biz.smp.usecase.impl;
|
|||||||
import io.shinhanlife.dap.mcc.biz.smp.dto.TeamMemberRequest;
|
import io.shinhanlife.dap.mcc.biz.smp.dto.TeamMemberRequest;
|
||||||
import io.shinhanlife.dap.mcc.biz.smp.dto.TeamMemberResponse;
|
import io.shinhanlife.dap.mcc.biz.smp.dto.TeamMemberResponse;
|
||||||
import io.shinhanlife.dap.mcc.biz.smp.usecase.TeamMemberUseCase;
|
import io.shinhanlife.dap.mcc.biz.smp.usecase.TeamMemberUseCase;
|
||||||
import io.shinhanlife.dap.lib.usecase.AbstractMcpToolUseCase;
|
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package io.shinhanlife.dap.mcc.biz.smp.usecase.impl;
|
|||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.shinhanlife.dap.mcc.biz.smp.usecase.WeatherToolUseCase;
|
import io.shinhanlife.dap.mcc.biz.smp.usecase.WeatherToolUseCase;
|
||||||
import io.shinhanlife.dap.lib.usecase.AbstractMcpToolUseCase;
|
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||||
import io.shinhanlife.dap.mcc.biz.smp.dto.WeatherRequest;
|
import io.shinhanlife.dap.mcc.biz.smp.dto.WeatherRequest;
|
||||||
import io.shinhanlife.dap.mcc.biz.smp.dto.WeatherResponse;
|
import io.shinhanlife.dap.mcc.biz.smp.dto.WeatherResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.shinhanlife.dap.mcc.biz.sms.usecase.impl;
|
package io.shinhanlife.dap.mcc.biz.sms.usecase.impl;
|
||||||
|
|
||||||
import io.shinhanlife.dap.mcc.biz.sms.usecase.SmsToolUseCase;
|
import io.shinhanlife.dap.mcc.biz.sms.usecase.SmsToolUseCase;
|
||||||
import io.shinhanlife.dap.lib.usecase.AbstractMcpToolUseCase;
|
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import io.shinhanlife.dap.mcc.biz.sms.converter.SmsLegacyConverter;
|
import io.shinhanlife.dap.mcc.biz.sms.converter.SmsLegacyConverter;
|
||||||
import io.shinhanlife.dap.mcc.biz.sms.dto.SmsSendRequest;
|
import io.shinhanlife.dap.mcc.biz.sms.dto.SmsSendRequest;
|
||||||
|
|||||||
Reference in New Issue
Block a user