소스 경로 변경
This commit is contained in:
125
add_javadoc.py
125
add_javadoc.py
@@ -1,125 +0,0 @@
|
||||
import os
|
||||
import re
|
||||
|
||||
JAVADOC_FILES = [
|
||||
r'.\McpBridge.java',
|
||||
r'.\dap-common\src\main\java\io\shinhanlife\dap\common\mcp\exception\GlobalExceptionHandler.java',
|
||||
r'.\dap-common\src\main\java\io\shinhanlife\dap\common\util\ToolSourceUpdater.java',
|
||||
r'.\dap-common\src\main\java\io\shinhanlife\glow\GlowAppServiceId.java',
|
||||
r'.\dap-common\src\main\java\io\shinhanlife\glow\GlowControllerId.java',
|
||||
r'.\dap-common\src\main\java\io\shinhanlife\glow\GlowIndexPaging.java',
|
||||
r'.\dap-common\src\main\java\io\shinhanlife\glow\GlowMciFieldInfo.java',
|
||||
r'.\dap-common\src\main\java\io\shinhanlife\glow\GlowMybatisMapper.java',
|
||||
r'.\dap-common\src\main\java\io\shinhanlife\glow\GlowServiceGroupId.java',
|
||||
r'.\dap-common\src\main\java\io\shinhanlife\glow\GlowTrgmField.java',
|
||||
r'.\dap-common\src\test\java\io\shinhanlife\glow\util\GlowMciParserTest.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\DapGatewayApplication.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\audit\AuditLogService.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\config\AgentResponseBudgetProperties.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\config\McpGatewayProperties.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\guardrail\GuardrailService.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\guardrail\SensitiveDataMasker.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\guardrail\ToolResponseGuardrailService.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\presentation\ChatController.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\presentation\McpRouterController.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\presentation\ScaffoldingController.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\redis\McpMonitorEventService.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\redis\RedisToolTraceService.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\resilience\CircuitBreaker.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\resilience\CircuitBreakerMonitorController.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\resilience\CircuitBreakerService.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\resilience\CircuitBreakerSnapshot.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\resilience\CircuitBreakerState.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\resilience\FailureType.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\resilience\RetryPolicy.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\resilience\ToolExecutionException.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\security\McpRequestContext.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\security\McpRequestContextResolver.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\security\ToolAuthorizationService.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\service\ExecuteService.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\sync\DynamicMcpController.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\sync\DynamicMcpServerManager.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\sync\RegistryMcpToolSpecificationFactory.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\tool\large\AgentResponseBudgetService.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\tool\large\LargeToolResponseService.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\tool\large\PaginationRequestValidator.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\tool\result\ToolExecutionResult.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\tool\result\ToolExecutionResultFormatter.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\transport\HttpToolInvoker.java',
|
||||
r'.\dap-gateway\src\main\java\io\shinhanlife\dap\biz\mcp\gateway\transport\ToolInvoker.java',
|
||||
r'.\dap-gateway\src\test\java\io\shinhanlife\dap\biz\mcp\gateway\DapGatewayApplicationTests.java',
|
||||
r'.\dap-gateway\src\test\java\io\shinhanlife\dap\biz\mcp\gateway\tool\large\PaginationRequestValidatorTest.java',
|
||||
r'.\dap-tool-core\src\main\java\io\shinhanlife\dap\biz\mcp\sample\converter\SampleLegacyConverter.java',
|
||||
r'.\dap-tool-core\src\main\java\io\shinhanlife\dap\biz\mcp\sample\dto\SampleAiReqDto.java',
|
||||
r'.\dap-tool-core\src\main\java\io\shinhanlife\dap\biz\mcp\tool\annotation\McpFunction.java',
|
||||
r'.\dap-tool-core\src\main\java\io\shinhanlife\dap\biz\mcp\tool\annotation\McpParameter.java',
|
||||
r'.\dap-tool-core\src\main\java\io\shinhanlife\dap\biz\mcp\tool\annotation\McpTool.java',
|
||||
r'.\dap-tool-core\src\main\java\io\shinhanlife\dap\biz\mcp\tool\aop\ToolSlaMonitoringAspect.java',
|
||||
r'.\dap-tool-core\src\main\java\io\shinhanlife\dap\biz\mcp\tool\presentation\BusinessToolController.java',
|
||||
r'.\dap-tool-core\src\main\java\io\shinhanlife\dap\biz\mcp\tool\service\ToolRegistryHeartbeatSender.java',
|
||||
r'.\dap-tool-core\src\main\java\io\shinhanlife\dap\biz\mcp\tool\util\JsonSchemaGenerator.java',
|
||||
r'.\dap-tool-core\src\test\java\io\shinhanlife\dap\biz\mcp\sample\converter\SampleLegacyConverterTest.java',
|
||||
r'.\dap-tool-email\src\main\java\io\shinhanlife\dap\biz\mcp\tool\email\DapToolEmailApplication.java',
|
||||
r'.\dap-tool-other\src\main\java\io\shinhanlife\dap\biz\mcp\tool\dto\BalanceReq.java',
|
||||
r'.\dap-tool-other\src\main\java\io\shinhanlife\dap\biz\mcp\tool\dto\BalanceRes.java',
|
||||
r'.\dap-tool-other\src\main\java\io\shinhanlife\dap\biz\mcp\tool\other\DapToolOtherApplication.java',
|
||||
r'.\dap-tool-other\src\main\java\io\shinhanlife\dap\biz\mcp\tool\service\BalanceService.java',
|
||||
r'.\dap-tool-payment\src\main\java\io\shinhanlife\dap\biz\mcp\tool\payment\DapToolPaymentApplication.java',
|
||||
r'.\dap-tool-sms\src\main\java\io\shinhanlife\dap\biz\mcp\tool\sms\DapToolSmsApplication.java',
|
||||
r'.\dap-tool-sms\src\main\java\io\shinhanlife\dap\biz\mcp\tool\sms\converter\SmsLegacyConverter.java',
|
||||
r'.\dap-tool-sms\src\main\java\io\shinhanlife\dap\biz\mcp\tool\sms\dto\SmsLegacyReqDto.java',
|
||||
]
|
||||
|
||||
JAVADOC_TEMPLATE = '''/**
|
||||
* @package {package}
|
||||
* @className {classname}
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 김형식
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 김형식 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/'''
|
||||
|
||||
def get_package_and_class(content, filename):
|
||||
pkg_match = re.search(r'^package\s+([^\s;]+)', content, re.MULTILINE)
|
||||
package = pkg_match.group(1) if pkg_match else 'io.shinhanlife'
|
||||
classname = os.path.splitext(filename)[0]
|
||||
return package, classname
|
||||
|
||||
def add_javadoc(file_path):
|
||||
if not os.path.exists(file_path):
|
||||
print(f'SKIP (not found): {file_path}')
|
||||
return
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
if '@className' in content or '@author' in content:
|
||||
print(f'SKIP (already has javadoc): {file_path}')
|
||||
return
|
||||
|
||||
filename = os.path.basename(file_path)
|
||||
package, classname = get_package_and_class(content, filename)
|
||||
javadoc = JAVADOC_TEMPLATE.format(package=package, classname=classname)
|
||||
|
||||
# Insert after package declaration
|
||||
pkg_pattern = re.compile(r'^(package\s+[^\s;]+;\s*\n)', re.MULTILINE)
|
||||
match = pkg_pattern.search(content)
|
||||
if match:
|
||||
insert_pos = match.end()
|
||||
new_content = content[:insert_pos] + '\n' + javadoc + '\n' + content[insert_pos:]
|
||||
else:
|
||||
new_content = javadoc + '\n' + content
|
||||
|
||||
with open(file_path, 'w', encoding='utf-8') as f:
|
||||
f.write(new_content)
|
||||
print(f'OK: {file_path}')
|
||||
|
||||
for f in JAVADOC_FILES:
|
||||
add_javadoc(f)
|
||||
|
||||
print('\nDone!')
|
||||
161
chaos_test.py
161
chaos_test.py
@@ -1,161 +0,0 @@
|
||||
import requests
|
||||
import json
|
||||
import threading
|
||||
import time
|
||||
|
||||
BASE_URL = "https://axhub-gateway.onrender.com/mcp/custom/common"
|
||||
TOOL_NAME = "other_get_current_weather"
|
||||
|
||||
results = []
|
||||
|
||||
def run_test(test_name, payload_args):
|
||||
print(f"\n[{test_name}] 시작...")
|
||||
|
||||
try:
|
||||
# 1. Initialize (서버 슬립 해제 포함, 타임아웃 넉넉하게)
|
||||
init_resp = requests.post(BASE_URL, json={
|
||||
"jsonrpc": "2.0", "id": 1, "method": "initialize",
|
||||
"params": {
|
||||
"protocolVersion": "2025-06-18",
|
||||
"capabilities": {},
|
||||
"clientInfo": {"name": "chaos-tester", "version": "1.0.0"}
|
||||
}
|
||||
}, stream=True, timeout=60)
|
||||
|
||||
session_id = init_resp.headers.get("Mcp-Session-Id")
|
||||
if not session_id:
|
||||
results.append({"name": test_name, "payload": str(payload_args), "result": "세션 수립 실패", "safety": "알 수 없음"})
|
||||
print(f" 세션 수립 실패")
|
||||
return
|
||||
|
||||
print(f" 세션 ID: {session_id[:16]}...")
|
||||
headers = {"Mcp-Session-Id": session_id}
|
||||
|
||||
sse_result = {"data": None, "raw": []}
|
||||
|
||||
def read_sse(resp):
|
||||
for line in resp.iter_lines():
|
||||
if line:
|
||||
decoded = line.decode("utf-8")
|
||||
sse_result["raw"].append(decoded)
|
||||
if decoded.startswith("data:"):
|
||||
raw = decoded[5:].strip()
|
||||
if raw and not raw.startswith("/mcp"):
|
||||
try:
|
||||
parsed = json.loads(raw)
|
||||
# tools/call 응답 (id=2)만 저장
|
||||
if parsed.get("id") == 2:
|
||||
sse_result["data"] = parsed
|
||||
except:
|
||||
pass
|
||||
|
||||
sse_thread = threading.Thread(target=read_sse, args=(init_resp,), daemon=True)
|
||||
sse_thread.start()
|
||||
time.sleep(1)
|
||||
|
||||
# 2. notifications/initialized
|
||||
requests.post(BASE_URL, json={"jsonrpc": "2.0", "method": "notifications/initialized"},
|
||||
headers=headers, timeout=30)
|
||||
time.sleep(0.5)
|
||||
|
||||
# 3. tools/call with chaos payload
|
||||
print(f" 페이로드 주입 중: {json.dumps(payload_args, ensure_ascii=False)[:80]}")
|
||||
call_resp = requests.post(BASE_URL, json={
|
||||
"jsonrpc": "2.0", "id": 2, "method": "tools/call",
|
||||
"params": {"name": TOOL_NAME, "arguments": payload_args}
|
||||
}, headers=headers, timeout=30)
|
||||
|
||||
print(f" HTTP Status: {call_resp.status_code}")
|
||||
|
||||
# SSE 응답 대기 (최대 5초)
|
||||
for _ in range(10):
|
||||
time.sleep(0.5)
|
||||
if sse_result["data"]:
|
||||
break
|
||||
|
||||
tool_result = sse_result["data"]
|
||||
http_status = call_resp.status_code
|
||||
|
||||
# 결과 분석
|
||||
server_died = False
|
||||
is_error = False
|
||||
response_summary = "SSE 응답 없음 (타임아웃)"
|
||||
|
||||
if tool_result:
|
||||
result_body = tool_result.get("result", {})
|
||||
error_body = tool_result.get("error", {})
|
||||
|
||||
if error_body:
|
||||
is_error = True
|
||||
response_summary = f"MCP Error: {json.dumps(error_body, ensure_ascii=False)[:100]}"
|
||||
elif isinstance(result_body, dict):
|
||||
is_err_flag = result_body.get("isError", False)
|
||||
content = result_body.get("content", [])
|
||||
text = content[0].get("text", "") if content else str(result_body)
|
||||
if is_err_flag or "500" in text or "Exception" in text:
|
||||
server_died = True
|
||||
response_summary = f"서버 에러: {text[:100]}"
|
||||
else:
|
||||
response_summary = f"정상 응답: {text[:100]}"
|
||||
elif http_status >= 500:
|
||||
server_died = True
|
||||
response_summary = f"HTTP {http_status} 서버 에러"
|
||||
|
||||
if server_died:
|
||||
safety = "위험 - 서버 500 에러"
|
||||
elif is_error:
|
||||
safety = "안전 - Validation 에러 반환"
|
||||
else:
|
||||
safety = f"실행됨 (HTTP {http_status})"
|
||||
|
||||
results.append({
|
||||
"name": test_name,
|
||||
"payload": json.dumps(payload_args, ensure_ascii=False)[:60],
|
||||
"result": response_summary,
|
||||
"safety": safety
|
||||
})
|
||||
|
||||
print(f" 결과: {response_summary}")
|
||||
print(f" 판정: {safety}")
|
||||
|
||||
except requests.exceptions.ReadTimeout:
|
||||
results.append({"name": test_name, "payload": str(payload_args), "result": "서버 응답 타임아웃", "safety": "판정 불가"})
|
||||
print(f" 타임아웃 발생")
|
||||
except Exception as e:
|
||||
results.append({"name": test_name, "payload": str(payload_args), "result": f"오류: {str(e)[:80]}", "safety": "판정 불가"})
|
||||
print(f" 오류: {e}")
|
||||
|
||||
|
||||
# ===== 서버 웨이크업 =====
|
||||
print("=" * 60)
|
||||
print("서버 웨이크업 중... (최초 응답에 시간이 걸릴 수 있습니다)")
|
||||
try:
|
||||
r = requests.get("https://axhub-gateway.onrender.com/actuator/health", timeout=60)
|
||||
print(f"서버 상태: {r.status_code}")
|
||||
except:
|
||||
print("헬스체크 엔드포인트 없음 - 바로 테스트 진행")
|
||||
|
||||
print("=" * 60)
|
||||
print(f"CHAOS TEST: {TOOL_NAME}")
|
||||
print("=" * 60)
|
||||
|
||||
# 1. 타입 브레이커: city에 10000자 문자열
|
||||
run_test("1. 타입 브레이커 (10000자 문자열)", {"city": "A" * 10000})
|
||||
time.sleep(2)
|
||||
|
||||
# 2. 필수 파라미터 누락
|
||||
run_test("2. 필수 파라미터 누락 (city 없음)", {})
|
||||
time.sleep(2)
|
||||
|
||||
# 3. XSS + SQL Injection
|
||||
run_test("3. 악의적 페이로드 (XSS + SQL Injection)", {"city": "<script>alert(1)</script>' OR 1=1 --"})
|
||||
|
||||
# ===== 결과 리포트 =====
|
||||
print("\n\n" + "=" * 80)
|
||||
print("CHAOS TEST 결과 리포트 - other_get_current_weather")
|
||||
print("=" * 80)
|
||||
print(f"{'테스트 시나리오':<35} {'판정':<30} {'서버 응답'}")
|
||||
print("-" * 100)
|
||||
for r in results:
|
||||
print(f"{r['name']:<35} {r['safety']:<30} {r['result'][:40]}")
|
||||
print("=" * 80)
|
||||
@@ -1,8 +1,9 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.email.service;
|
||||
|
||||
import io.shinhanlife.dap.mcc.annotation.McpFunction;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpTool;
|
||||
import io.shinhanlife.dap.mcc.dto.EmailSendReq;
|
||||
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.other.service;
|
||||
|
||||
|
||||
/**
|
||||
@@ -1,13 +1,15 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.other.service;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpFunction;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpTool;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import io.shinhanlife.dap.mcc.dto.BillingStatusReq;
|
||||
import io.shinhanlife.dap.mcc.dto.BillingProcessReq;
|
||||
import io.shinhanlife.dap.mcc.dto.BillingStatusReq;
|
||||
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@McpTool(
|
||||
routingType = "MCI",
|
||||
@@ -1,9 +1,10 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.other.service;
|
||||
|
||||
import io.shinhanlife.dap.mcc.annotation.McpFunction;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpTool;
|
||||
import io.shinhanlife.dap.mcc.dto.BondCheckReq;
|
||||
import io.shinhanlife.dap.mcc.dto.BondIssueReq;
|
||||
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
|
||||
|
||||
@McpTool(
|
||||
routingType = "EAI",
|
||||
@@ -1,10 +1,10 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.other.service;
|
||||
|
||||
import io.shinhanlife.dap.mcc.annotation.McpFunction;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpTool;
|
||||
import io.shinhanlife.dap.mcc.dto.LeaveCountReq;
|
||||
import io.shinhanlife.dap.mcc.dto.VacationRegisterReq;
|
||||
import io.shinhanlife.dap.mcc.dto.LeaveCountReq;
|
||||
import io.shinhanlife.dap.mcc.dto.LeaveCountReq;
|
||||
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
|
||||
|
||||
@McpTool(
|
||||
routingType = "HTTP",
|
||||
@@ -1,9 +1,10 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.other.service;
|
||||
|
||||
import io.shinhanlife.dap.mcc.annotation.McpFunction;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpTool;
|
||||
import io.shinhanlife.dap.mcc.dto.ContractStatusReq;
|
||||
import io.shinhanlife.dap.mcc.dto.ContractDetailReq;
|
||||
import io.shinhanlife.dap.mcc.dto.ContractStatusReq;
|
||||
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
|
||||
|
||||
@McpTool(
|
||||
routingType = "HTTP",
|
||||
@@ -1,9 +1,10 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.other.service;
|
||||
|
||||
import io.shinhanlife.dap.mcc.annotation.McpFunction;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpTool;
|
||||
import io.shinhanlife.dap.mcc.dto.CustomerGradeReq;
|
||||
import io.shinhanlife.dap.mcc.dto.CustomerDetailReq;
|
||||
import io.shinhanlife.dap.mcc.dto.CustomerGradeReq;
|
||||
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
|
||||
|
||||
@McpTool(
|
||||
routingType = "TCP",
|
||||
@@ -1,9 +1,11 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.other.service;
|
||||
|
||||
import io.shinhanlife.dap.mcc.annotation.McpFunction;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpTool;
|
||||
import org.springframework.stereotype.Service;
|
||||
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.other.service;
|
||||
|
||||
import io.shinhanlife.dap.mcc.annotation.McpFunction;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpTool;
|
||||
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.service
|
||||
@@ -1,13 +1,13 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.other.service;
|
||||
|
||||
import io.shinhanlife.dap.common.integration.mci.component.AxhubMciComponent;
|
||||
import io.shinhanlife.glow.communication.dto.Transfer;
|
||||
import org.springframework.stereotype.Service;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpFunction;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpTool;
|
||||
import io.shinhanlife.dap.mcc.dto.Onnba3011ReqDto;
|
||||
import io.shinhanlife.glow.communication.dto.Transfer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.service
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.other.service;
|
||||
|
||||
import io.shinhanlife.dap.common.adapter.sender.ShinhanMciSender;
|
||||
import io.shinhanlife.dap.common.integration.mci.dto.MciRequestWrapper;
|
||||
@@ -1,13 +1,15 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.other.service;
|
||||
|
||||
import io.shinhanlife.dap.mcc.annotation.McpFunction;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpTool;
|
||||
import io.shinhanlife.dap.mcc.dto.MciSampleStringRes;
|
||||
import io.shinhanlife.dap.mcc.dto.SampleStringReq;
|
||||
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
|
||||
import io.shinhanlife.glow.util.GlowMciParser;
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.Map;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.service
|
||||
@@ -1,13 +1,15 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.other.service;
|
||||
|
||||
import io.shinhanlife.dap.mcc.annotation.McpFunction;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpTool;
|
||||
import io.shinhanlife.dap.mcc.dto.TemplateDownloadReq;
|
||||
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@@ -1,14 +1,16 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.other.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpFunction;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpTool;
|
||||
import io.shinhanlife.dap.mcc.dto.WeatherReq;
|
||||
import io.shinhanlife.dap.mcc.dto.WeatherRes;
|
||||
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package io.shinhanlife.dap.mcc.service;
|
||||
package io.shinhanlife.dap.mcc.payment.service;
|
||||
|
||||
import io.shinhanlife.dap.mcc.annotation.McpFunction;
|
||||
import io.shinhanlife.dap.mcc.annotation.McpTool;
|
||||
import io.shinhanlife.dap.mcc.dto.PaymentApprovalReq;
|
||||
import io.shinhanlife.dap.mcc.dto.PaymentApprovalRes;
|
||||
import org.springframework.stereotype.Service;
|
||||
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -1,296 +0,0 @@
|
||||
import re
|
||||
import os
|
||||
|
||||
FILE_PATH = r"c:\Users\Admin\IdeaProjects\axhub-backend-main\dap-tool-core\src\main\java\io\shinhanlife\dap\common\util\ToolScaffolder.java"
|
||||
|
||||
with open(FILE_PATH, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
part1_start = content.find('String toolName = baseName.isEmpty() ? baseName : Character.toLowerCase(baseName.charAt(0)) + baseName.substring(1);')
|
||||
part1_end = content.find('log.append("\\n=========================================\\n");')
|
||||
|
||||
if part1_start == -1 or part1_end == -1:
|
||||
print("Could not find the target block.")
|
||||
exit(1)
|
||||
|
||||
new_block = '''String toolName = baseName.isEmpty() ? baseName : Character.toLowerCase(baseName.charAt(0)) + baseName.substring(1);
|
||||
|
||||
boolean isMci = "MCI".equalsIgnoreCase(routingType);
|
||||
String serviceContent;
|
||||
|
||||
if (isMci) {
|
||||
serviceContent = """
|
||||
package %s.service;
|
||||
|
||||
import %s.annotation.McpFunction;
|
||||
import %s.annotation.McpTool;
|
||||
import %s.dto.%sReq;
|
||||
import %s.dto.%sRes;
|
||||
import io.shinhanlife.dap.common.integration.mci.component.AxhubMciComponent;
|
||||
import io.shinhanlife.glow.communication.dto.Transfer;
|
||||
import org.springframework.stereotype.Service;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @package %s.service
|
||||
* @className %sService
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author %s
|
||||
* @create %s
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* %s %s 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@McpTool(
|
||||
routingType = "%s",
|
||||
categoryKey = "%s"
|
||||
)
|
||||
public class %sService {
|
||||
|
||||
private final AxhubMciComponent mci;
|
||||
|
||||
@McpFunction(
|
||||
displayName = "%s 툴",
|
||||
name = "%s",
|
||||
description = "%s",
|
||||
prompt = "%s",
|
||||
mappingId = "%s",
|
||||
register = %s,
|
||||
requiresApproval = false,
|
||||
openWorldHint = true
|
||||
)
|
||||
public Object execute(%sReq req) {
|
||||
log.info("[MCI Tool] {} 요청 수신.", "%s");
|
||||
try {
|
||||
Transfer<Object> resTransfer = mci.callTo(
|
||||
"%s",
|
||||
null,
|
||||
req,
|
||||
Object.class
|
||||
);
|
||||
return resTransfer.getBody() != null ? resTransfer.getBody() : "{\\"status\\":\\"SUCCESS\\"}";
|
||||
} catch (Exception e) {
|
||||
log.error("[MCI Tool] 연동 중 오류 발생: {}", e.getMessage(), e);
|
||||
return "{\\"status\\":\\"ERROR\\", \\"message\\":\\"" + e.getMessage() + "\\"}";
|
||||
}
|
||||
}
|
||||
}
|
||||
""".formatted(
|
||||
BASE_PACKAGE,
|
||||
BASE_PACKAGE,
|
||||
BASE_PACKAGE,
|
||||
BASE_PACKAGE, baseName,
|
||||
BASE_PACKAGE, baseName,
|
||||
BASE_PACKAGE, baseName,
|
||||
author,
|
||||
createDate,
|
||||
createDate, author,
|
||||
routingType, group.toLowerCase(),
|
||||
baseName,
|
||||
baseName, toolName, description, description + " 해줘.", interfaceId, register,
|
||||
baseName,
|
||||
baseName, interfaceId
|
||||
);
|
||||
} else {
|
||||
serviceContent = """
|
||||
package %s.service;
|
||||
|
||||
import %s.annotation.McpFunction;
|
||||
import %s.annotation.McpTool;
|
||||
import %s.dto.%sReq;
|
||||
import %s.dto.%sRes;
|
||||
import %s.%s.converter.%sLegacyConverter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* @package %s.service
|
||||
* @className %sService
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author %s
|
||||
* @create %s
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* %s %s 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Service
|
||||
@McpTool(
|
||||
routingType = "%s",
|
||||
categoryKey = "%s"
|
||||
)
|
||||
public class %sService extends AbstractMcpToolService {
|
||||
|
||||
private final %sLegacyConverter converter = Mappers.getMapper(%sLegacyConverter.class);
|
||||
|
||||
@McpFunction(
|
||||
displayName = "%s 툴",
|
||||
name = "%s",
|
||||
description = "%s",
|
||||
prompt = "%s",
|
||||
mappingId = "%s",
|
||||
register = %s,
|
||||
requiresApproval = false
|
||||
)
|
||||
public Object execute(%sReq req) {
|
||||
// %sLegacyReq legacyReq = converter.toLegacyReq(req);
|
||||
return executeLegacy("%s", "%s", req); // Or pass legacyReq
|
||||
}
|
||||
}
|
||||
""".formatted(
|
||||
BASE_PACKAGE,
|
||||
BASE_PACKAGE,
|
||||
BASE_PACKAGE,
|
||||
BASE_PACKAGE, baseName,
|
||||
BASE_PACKAGE, baseName,
|
||||
BASE_PACKAGE, shortName, baseName,
|
||||
BASE_PACKAGE, baseName,
|
||||
author,
|
||||
createDate,
|
||||
createDate, author,
|
||||
routingType, group.toLowerCase(),
|
||||
baseName,
|
||||
baseName, toolName, description, description + " 해줘.", interfaceId, register,
|
||||
baseName,
|
||||
baseName,
|
||||
routingType, interfaceId
|
||||
);
|
||||
}
|
||||
|
||||
Files.writeString(serviceDir.resolve(baseName + "Service.java"), serviceContent);
|
||||
|
||||
if (!isMci) {
|
||||
String legacyReqContent = """
|
||||
package %s.%s.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @package %s.%s.dto
|
||||
* @className %sLegacyReq
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author %s
|
||||
* @create %s
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* %s %s 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Data
|
||||
public class %sLegacyReq {
|
||||
// TODO: Add legacy request fields here
|
||||
}
|
||||
""".formatted(BASE_PACKAGE, shortName, BASE_PACKAGE, shortName, baseName, author, createDate, createDate, author, baseName);
|
||||
Files.writeString(legacyDtoDir.resolve(baseName + "LegacyReq.java"), legacyReqContent);
|
||||
|
||||
String legacyResContent = """
|
||||
package %s.%s.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @package %s.%s.dto
|
||||
* @className %sLegacyRes
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author %s
|
||||
* @create %s
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* %s %s 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Data
|
||||
public class %sLegacyRes {
|
||||
// TODO: Add legacy response fields here
|
||||
}
|
||||
""".formatted(BASE_PACKAGE, shortName, BASE_PACKAGE, shortName, baseName, author, createDate, createDate, author, baseName);
|
||||
Files.writeString(legacyDtoDir.resolve(baseName + "LegacyRes.java"), legacyResContent);
|
||||
|
||||
String converterContent = """
|
||||
package %s.%s.converter;
|
||||
|
||||
import %s.dto.%sReq;
|
||||
import %s.dto.%sRes;
|
||||
import %s.%s.dto.%sLegacyReq;
|
||||
import %s.%s.dto.%sLegacyRes;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* @package %s.%s.converter
|
||||
* @className %sLegacyConverter
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author %s
|
||||
* @create %s
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* %s %s 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface %sLegacyConverter {
|
||||
|
||||
%sLegacyReq toLegacyReq(%sReq req);
|
||||
|
||||
%sRes toRes(%sLegacyRes legacyRes);
|
||||
}
|
||||
""".formatted(
|
||||
BASE_PACKAGE, shortName,
|
||||
BASE_PACKAGE, baseName,
|
||||
BASE_PACKAGE, baseName,
|
||||
BASE_PACKAGE, shortName, baseName,
|
||||
BASE_PACKAGE, shortName, baseName,
|
||||
BASE_PACKAGE, shortName, baseName, author, createDate, createDate, author,
|
||||
baseName, baseName, baseName, baseName, baseName, baseName
|
||||
);
|
||||
Files.writeString(converterDir.resolve(baseName + "LegacyConverter.java"), converterContent);
|
||||
}
|
||||
|
||||
'''
|
||||
|
||||
log_block_start = content.find('log.append("\\n=========================================\\n");')
|
||||
log_block_end = content.find('return log.toString();')
|
||||
|
||||
new_log_block = '''log.append("\\n=========================================\\n");
|
||||
log.append(" Scaffolding Complete! (Routing: " + routingType + ")\\n");
|
||||
log.append("=========================================\\n");
|
||||
log.append("[Service] ").append(serviceDir.resolve(baseName + "Service.java")).append("\\n");
|
||||
log.append("[Req DTO] ").append(dtoDir.resolve(baseName + "Req.java")).append("\\n");
|
||||
log.append("[Res DTO] ").append(dtoDir.resolve(baseName + "Res.java")).append("\\n");
|
||||
|
||||
if (!isMci) {
|
||||
log.append("[Legacy Req DTO] ").append(legacyDtoDir.resolve(baseName + "LegacyReq.java")).append("\\n");
|
||||
log.append("[Legacy Res DTO] ").append(legacyDtoDir.resolve(baseName + "LegacyRes.java")).append("\\n");
|
||||
log.append("[Legacy Converter] ").append(converterDir.resolve(baseName + "LegacyConverter.java")).append("\\n");
|
||||
}
|
||||
log.append("\\n Tip: ").append(interfaceId).append(" 목업 데이터를 mock-responses.json에 추가하세요.\\n");
|
||||
|
||||
'''
|
||||
|
||||
content = content[:part1_start] + new_block + new_log_block + content[log_block_end:]
|
||||
|
||||
with open(FILE_PATH, 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
|
||||
print("ToolScaffolder.java patched successfully.")
|
||||
@@ -1,72 +0,0 @@
|
||||
import requests
|
||||
import json
|
||||
import threading
|
||||
import time
|
||||
|
||||
URL = "https://axhub-gateway.onrender.com/mcp/custom/common"
|
||||
|
||||
def read_sse(response):
|
||||
print("\n[SSE Stream Open]")
|
||||
for line in response.iter_lines():
|
||||
if line:
|
||||
decoded_line = line.decode('utf-8')
|
||||
print(f"[SSE] {decoded_line}")
|
||||
if decoded_line.startswith("data:"):
|
||||
try:
|
||||
# Ignore the endpoint URL event which is not json
|
||||
if "sessionId=" in decoded_line:
|
||||
continue
|
||||
data = json.loads(decoded_line[5:])
|
||||
if "id" in data:
|
||||
print(f" => Received response for ID: {data['id']}")
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
|
||||
# 1. Initialize
|
||||
init_payload = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"method": "initialize",
|
||||
"params": {
|
||||
"protocolVersion": "2025-06-18",
|
||||
"capabilities": {},
|
||||
"clientInfo": {"name": "toolbox-executor", "version": "0.1.0"}
|
||||
}
|
||||
}
|
||||
print("1. Sending initialize request...")
|
||||
resp1 = requests.post(URL, json=init_payload, stream=True)
|
||||
print("HTTP Status:", resp1.status_code)
|
||||
session_id = resp1.headers.get("Mcp-Session-Id")
|
||||
print("Received Mcp-Session-Id:", session_id)
|
||||
|
||||
# Start reading SSE in a background thread
|
||||
sse_thread = threading.Thread(target=read_sse, args=(resp1,), daemon=True)
|
||||
sse_thread.start()
|
||||
|
||||
time.sleep(2) # Wait for init response to arrive via SSE
|
||||
|
||||
# 2. notifications/initialized
|
||||
print("\n2. Sending notifications/initialized...")
|
||||
notif_payload = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "notifications/initialized"
|
||||
}
|
||||
headers = {"Mcp-Session-Id": session_id, "MCP-Protocol-Version": "2025-06-18"}
|
||||
resp2 = requests.post(URL, json=notif_payload, headers=headers)
|
||||
print("HTTP Status:", resp2.status_code)
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
# 3. tools/list
|
||||
print("\n3. Sending tools/list...")
|
||||
list_payload = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 2,
|
||||
"method": "tools/list"
|
||||
}
|
||||
resp3 = requests.post(URL, json=list_payload, headers=headers)
|
||||
print("HTTP Status:", resp3.status_code)
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
print("\nFinished Deep Builder Test")
|
||||
@@ -1 +0,0 @@
|
||||
{"jsonrpc":"2.0","method":"tools/list","id":1}
|
||||
Reference in New Issue
Block a user