Merge branch 'main' of https://git.devjun.net/kimhyungsik/ax_hub_mcp_tool into juheelee
This commit is contained in:
@@ -14,14 +14,14 @@ import java.util.Map;
|
||||
/**
|
||||
* @package io.shinhanlife.dat.mcg.service
|
||||
* @className ToolPlanner
|
||||
* @description AX HUB ?<3F>스??처리 ?<3F>래??
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정?<3F>력 ----------
|
||||
* ?<3F>정?? ?<3F>정?? ?<3F>정?<3F>용
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초?<3F>성
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@@ -35,25 +35,25 @@ public class ToolPlanner {
|
||||
private final GatewayFallbackProperties fallbackProperties;
|
||||
|
||||
/**
|
||||
* ?<3F>청(payload)??분석?<3F>여 ?<3F>행?<3F>야 ??Tool??계획???<3F>성?<3F>니??
|
||||
* 요청(payload)을 분석하여 실행해야 할 Tool의 계획을 생성합니다.
|
||||
*/
|
||||
public Object createPlan(Map<String, Object> payload, String tenantId) {
|
||||
log.info(" [Planner] ?<3F>청 분석 <EFBFBD>??<3F>행 계획 ?<3F>립 ?<3F>작");
|
||||
log.info(" [Planner] 요청 분석 및 실행 계획 수립 시작");
|
||||
|
||||
// 1. ?<3F>청?<3F>서 ?<3F>출?<3F>려?????<3F>름 추출 (JSON-RPC params.name)
|
||||
// 1. 요청에서 호출하려는 툴 이름 추출 (JSON-RPC params.name)
|
||||
Map<String, Object> params = (Map<String, Object>) payload.get("params");
|
||||
String toolName = params != null ? (String) params.get("name") : null;
|
||||
|
||||
if (toolName == null || toolName.isEmpty()) {
|
||||
throw new IllegalArgumentException("?<3F>청??toolName???<3F>함?<3F>어 ?<3F><>? ?<3F>습?<3F>다.");
|
||||
throw new IllegalArgumentException("요청에 toolName이 포함되어 있지 않습니다.");
|
||||
}
|
||||
|
||||
// 2. RedisRegistry?<3F>서 ?<3F>당 ?<3F>의 메<>??<3F>이??조회
|
||||
// (?<3F>제로는 ??메<>??<3F>이?<3F><>? ?<3F>행 계획???<3F>심???<3F>니??
|
||||
// 2. RedisRegistry에서 해당 툴의 메타데이터 조회
|
||||
// (실제로는 이 메타데이터가 실행 계획의 핵심이 됩니다)
|
||||
var toolMetadata = InMemoryRegistryService.getToolByName(toolName);
|
||||
|
||||
if (toolMetadata == null) {
|
||||
log.warn(" [Planner] ?<3F>록?<3F><>? ?<3F><>? ???<3F>청: {}. Fallback ?<3F>우??규칙???<3F>인?<3F>니??", toolName);
|
||||
log.warn(" [Planner] 등록되지 않은 툴 요청: {}. Fallback 라우팅 규칙을 확인합니다.", toolName);
|
||||
|
||||
String fallbackPodUrl = fallbackProperties.getDefaultUrl();
|
||||
if (fallbackProperties.getRoutes() != null) {
|
||||
@@ -66,11 +66,11 @@ public class ToolPlanner {
|
||||
}
|
||||
|
||||
if (fallbackPodUrl == null || fallbackPodUrl.isEmpty()) {
|
||||
log.error(" [Planner] Fallback ?<3F>우???<3F>?<3F>이 ?<3F>닙?<3F>다. ?? {}", toolName);
|
||||
throw new RuntimeException("?<3F>당 ??" + toolName + ")???<3F><>??<3F>트리에 존재?<3F><>? ?<3F>습?<3F>다.");
|
||||
log.error(" [Planner] Fallback 라우팅 대상이 아닙니다. 툴: {}", toolName);
|
||||
throw new RuntimeException("해당 툴(" + toolName + ")이 레지스트리에 존재하지 않습니다.");
|
||||
}
|
||||
|
||||
log.info(" [Planner] Fallback ?<3F>우??매칭?? {} -> {}", toolName, fallbackPodUrl);
|
||||
log.info(" [Planner] Fallback 라우팅 매칭됨: {} -> {}", toolName, fallbackPodUrl);
|
||||
|
||||
toolMetadata = ToolMetadata.builder()
|
||||
.uid(toolName)
|
||||
@@ -80,26 +80,26 @@ public class ToolPlanner {
|
||||
.build();
|
||||
}
|
||||
|
||||
// 2-1. [?<3F>규] ?<3F>메??그룹??기반 권한 검<EFBFBD>?
|
||||
// 2-1. [신규] 도메인 그룹핑 기반 권한 검증
|
||||
if (tenantId != null && !tenantId.equalsIgnoreCase("system") && toolMetadata.getCategoryKey() != null) {
|
||||
String normalizedTenantId = tenantId.toLowerCase();
|
||||
List<String> allowedDomains = securityProperties.getTenantDomains().get(normalizedTenantId);
|
||||
|
||||
// 만약 ?<3F>?<3F>문??변???<3F>에???<3F>으<EFBFBD>??<3F>래 값으<EAB092>???<3F>????<3F>도 (?<3F>위 ?<3F>환??
|
||||
// 만약 대소문자 변환 후에도 없으면 원래 값으로 한 번 더 시도 (하위 호환성)
|
||||
if (allowedDomains == null) {
|
||||
allowedDomains = securityProperties.getTenantDomains().get(tenantId);
|
||||
}
|
||||
|
||||
if (allowedDomains == null ||
|
||||
(!allowedDomains.contains("ALL") && !allowedDomains.contains(toolMetadata.getCategoryKey()))) {
|
||||
log.warn(" [Planner] 권한 거<EFBFBD>? - Tenant: {}, Request Domain: {}", tenantId, toolMetadata.getCategoryKey());
|
||||
throw new SecurityException("?<3F>당 ?<3F>메??" + toolMetadata.getCategoryKey() + ")???<3F>을 ?<3F>행??권한???<3F>습?<3F>다.");
|
||||
log.warn(" [Planner] 권한 거부 - Tenant: {}, Request Domain: {}", tenantId, toolMetadata.getCategoryKey());
|
||||
throw new SecurityException("해당 도메인(" + toolMetadata.getCategoryKey() + ")의 툴을 실행할 권한이 없습니다.");
|
||||
}
|
||||
}
|
||||
|
||||
log.info(" [Planner] ??'{}'???<3F>???<3F>행 계획 ?<3F>립 ?<3F>료", toolName);
|
||||
log.info(" [Planner] 툴 '{}'에 대한 실행 계획 수립 완료", toolName);
|
||||
|
||||
// 3. ?<3F>립??계획(??메<>??<3F>이?? 반환
|
||||
// 3. 수립된 계획(툴 메타데이터) 반환
|
||||
return toolMetadata;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user