Compare commits
10 Commits
05388566ba
...
d867551248
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d867551248 | ||
|
|
7edda9aa9e | ||
|
|
b431988ee6 | ||
|
|
d87af0cc82 | ||
|
|
3131440171 | ||
|
|
f8f17e7ea7 | ||
|
|
fce3df35c9 | ||
|
|
4b45acbded | ||
|
|
aceb1a9799 | ||
|
|
145ca90ed1 |
@@ -10,6 +10,7 @@
|
||||
## 명심해야 할 규칙 추가란
|
||||
* 이모지는 무조건 넣지 않는다
|
||||
* import 할것 무조건 한다
|
||||
* Git commit과 push는 사용자의 명시적인 허락(지시) 없이는 절대 수행하지 않는다.
|
||||
* 자바 만들때는 무조건 아래 내용을 넣는다
|
||||
/**
|
||||
* @package io.shinhanlife.axhub.biz.mcp.tool.sms
|
||||
|
||||
@@ -137,6 +137,9 @@ public class PodScaffolder {
|
||||
|
||||
# Auto Prefix Namespace
|
||||
mcp.namespace=%s
|
||||
|
||||
# API 보안 키 설정
|
||||
mcp.security.tenant-domains.TESTER-DEV=ALL
|
||||
""".formatted(portStr, moduleName, shortName);
|
||||
Files.writeString(resPath.resolve("application.properties"), applicationProperties);
|
||||
|
||||
@@ -170,6 +173,23 @@ public class PodScaffolder {
|
||||
""";
|
||||
Files.writeString(resPath.resolve("application-local.properties"), applicationLocalProperties);
|
||||
|
||||
String applicationDevProperties = """
|
||||
# Render 클라우드 환경 전용 설정
|
||||
axhub.gateway.url=https://axhub-gateway.onrender.com
|
||||
axhub.tool.url=https://%s.onrender.com
|
||||
|
||||
# EIMS 동적 라우팅 접속 정보 (Mock)
|
||||
eims.http.url=http://localhost:${server.port}/api/gateway
|
||||
eims.tcp.host=127.0.0.1
|
||||
eims.tcp.port=8090
|
||||
eims.tcp.timeout=5000
|
||||
eims.jsp.form.url=http://localhost:${server.port}/mock/jsp-form
|
||||
eims.jsp.json.url=http://localhost:${server.port}/mock/jsp-json
|
||||
eims.mci.url=http://localhost:${server.port}/api/mock/esb/api
|
||||
eims.mcistring.url=http://localhost:${server.port}/api/mock/esb/string
|
||||
""".formatted(moduleName);
|
||||
Files.writeString(resPath.resolve("application-dev.properties"), applicationDevProperties);
|
||||
|
||||
String logbackXml = """
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
@@ -62,8 +62,11 @@ public class McpRouterController {
|
||||
|
||||
@PostMapping("/tools/call")
|
||||
public ResponseEntity<?> callTool(@RequestBody Map<String, Object> payload,
|
||||
@RequestHeader(value = "X-Agent-Id", required = false) String agentId,
|
||||
@RequestHeader(value = "X-Tenant-Id", required = false, defaultValue = "system") String tenantId) {
|
||||
|
||||
String effectiveTenantId = (agentId != null && !agentId.trim().isEmpty()) ? agentId : tenantId;
|
||||
|
||||
try {
|
||||
log.info("[Admin UI -> MCP Gateway] 동적 툴 실행 요청 수신: {}", objectMapper.writeValueAsString(payload));
|
||||
} catch (Exception ex) {
|
||||
@@ -71,7 +74,7 @@ public class McpRouterController {
|
||||
}
|
||||
|
||||
try {
|
||||
Object result = executeService.execute(payload, tenantId);
|
||||
Object result = executeService.execute(payload, effectiveTenantId);
|
||||
|
||||
io.shinhanlife.axhub.biz.mcp.adapter.dto.JsonRpcResponse response = new io.shinhanlife.axhub.biz.mcp.adapter.dto.JsonRpcResponse();
|
||||
response.setJsonrpc("2.0");
|
||||
@@ -89,7 +92,7 @@ public class McpRouterController {
|
||||
log.warn(" [보안 차단] 권한 오류: {}", se.getMessage());
|
||||
return ResponseEntity.status(403).body(Map.of("error", se.getMessage()));
|
||||
} catch (Exception e) {
|
||||
log.error(" 파이프라인 실행 중 오류: {}", e.getMessage());
|
||||
log.error(" 파이프라인 실행 중 오류:", e);
|
||||
return ResponseEntity.internalServerError().body(Map.of("error", e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,9 +166,17 @@ public class ExecuteService {
|
||||
|
||||
private Object executeWithResilience(McpRequestContext context, ToolMetadata metadata, ObjectNode arguments, Map<String, Object> payload) {
|
||||
RetryPolicy retryPolicy = retryPolicy(metadata, arguments);
|
||||
|
||||
int failureThreshold = (metadata.getCircuitBreakerFailureThreshold() != null && metadata.getCircuitBreakerFailureThreshold() > 0)
|
||||
? metadata.getCircuitBreakerFailureThreshold()
|
||||
: properties.circuitBreakerFailureThreshold();
|
||||
|
||||
long openMillis = (metadata.getCircuitBreakerOpenMillis() != null && metadata.getCircuitBreakerOpenMillis() > 0)
|
||||
? metadata.getCircuitBreakerOpenMillis()
|
||||
: properties.circuitBreakerOpenMillis();
|
||||
|
||||
CircuitBreaker circuitBreaker = circuitBreakerService.breaker("tool:" + metadata.getName(),
|
||||
metadata.getCircuitBreakerFailureThreshold(),
|
||||
metadata.getCircuitBreakerOpenMillis());
|
||||
failureThreshold, openMillis);
|
||||
|
||||
ToolExecutionException lastError = null;
|
||||
for (int attempt = 1; attempt <= retryPolicy.maxAttempts(); attempt++) {
|
||||
|
||||
@@ -82,7 +82,14 @@ public class ToolPlanner {
|
||||
|
||||
// 2-1. [신규] 도메인 그룹핑 기반 권한 검증
|
||||
if (tenantId != null && toolMetadata.getCategoryKey() != null) {
|
||||
List<String> allowedDomains = securityProperties.getTenantDomains().get(tenantId);
|
||||
String normalizedTenantId = tenantId.toLowerCase();
|
||||
List<String> allowedDomains = securityProperties.getTenantDomains().get(normalizedTenantId);
|
||||
|
||||
// 만약 대소문자 변환 후에도 없으면 원래 값으로 한 번 더 시도 (하위 호환성)
|
||||
if (allowedDomains == null) {
|
||||
allowedDomains = securityProperties.getTenantDomains().get(tenantId);
|
||||
}
|
||||
|
||||
if (allowedDomains == null ||
|
||||
(!allowedDomains.contains("ALL") && !allowedDomains.contains(toolMetadata.getCategoryKey()))) {
|
||||
log.warn(" [Planner] 권한 거부 - Tenant: {}, Request Domain: {}", tenantId, toolMetadata.getCategoryKey());
|
||||
|
||||
@@ -41,6 +41,8 @@ mcp.max-stream-bytes=1048576
|
||||
mcp.max-response-bytes-from-tool=5242880
|
||||
mcp.tool-registry-sync-interval-millis=5000
|
||||
|
||||
# API 보안 키 설정
|
||||
mcp.security.tenant-domains.TESTER-DEV=ALL
|
||||
# Spring AI OpenAI / Gemini API Config
|
||||
spring.ai.openai.api-key=AQ.Ab8RN6KFZggsQf8iooY1v_3h3vp2TIjiYB54dV4Yay3vVKEMtg
|
||||
spring.ai.openai.base-url=https://generativelanguage.googleapis.com/v1beta/openai/
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# Render 클라우드 환경 전용 설정
|
||||
server.port=${PORT:8083}
|
||||
axhub.gateway.url=https://axhub-gateway.onrender.com
|
||||
axhub.tool.url=https://axhub-tool-email.onrender.com
|
||||
|
||||
# EIMS 동적 라우팅 접속 정보 (Mock)
|
||||
eims.http.url=http://localhost:${server.port}/api/gateway
|
||||
eims.tcp.host=127.0.0.1
|
||||
eims.tcp.port=8090
|
||||
eims.tcp.timeout=5000
|
||||
eims.jsp.form.url=http://localhost:${server.port}/mock/jsp-form
|
||||
eims.jsp.json.url=http://localhost:${server.port}/mock/jsp-json
|
||||
eims.mci.url=http://localhost:${server.port}/api/mock/esb/api
|
||||
eims.mcistring.url=http://localhost:${server.port}/api/mock/esb/string
|
||||
@@ -8,3 +8,6 @@ logging.level.org.apache.kafka=ERROR
|
||||
|
||||
# Auto Prefix Namespace
|
||||
mcp.namespace=email
|
||||
|
||||
# API 보안 키 설정
|
||||
mcp.security.tenant-domains.TESTER-DEV=ALL
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# Render 클라우드 환경 전용 설정
|
||||
server.port=${PORT:8084}
|
||||
axhub.gateway.url=https://axhub-gateway.onrender.com
|
||||
axhub.tool.url=https://axhub-tool-other.onrender.com
|
||||
|
||||
|
||||
@@ -8,3 +8,6 @@ logging.level.org.apache.kafka=ERROR
|
||||
|
||||
# Auto Prefix Namespace
|
||||
mcp.namespace=other
|
||||
|
||||
# API 보안 키 설정
|
||||
mcp.security.tenant-domains.TESTER-DEV=ALL
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# Render 클라우드 환경 전용 설정
|
||||
server.port=${PORT:8085}
|
||||
axhub.gateway.url=https://axhub-gateway.onrender.com
|
||||
axhub.tool.url=https://axhub-tool-payment.onrender.com
|
||||
|
||||
# EIMS 동적 라우팅 접속 정보 (Mock)
|
||||
eims.http.url=http://localhost:${server.port}/api/gateway
|
||||
eims.tcp.host=127.0.0.1
|
||||
eims.tcp.port=8090
|
||||
eims.tcp.timeout=5000
|
||||
eims.jsp.form.url=http://localhost:${server.port}/mock/jsp-form
|
||||
eims.jsp.json.url=http://localhost:${server.port}/mock/jsp-json
|
||||
eims.mci.url=http://localhost:${server.port}/api/mock/esb/api
|
||||
eims.mcistring.url=http://localhost:${server.port}/api/mock/esb/string
|
||||
@@ -2,3 +2,6 @@ spring.profiles.active=local
|
||||
|
||||
# Auto Prefix Namespace
|
||||
mcp.namespace=payment
|
||||
|
||||
# API 보안 키 설정
|
||||
mcp.security.tenant-domains.TESTER-DEV=ALL
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# Render 클라우드 환경 전용 설정
|
||||
server.port=${PORT:8082}
|
||||
axhub.gateway.url=https://axhub-gateway.onrender.com
|
||||
axhub.tool.url=https://axhub-tool-sms.onrender.com
|
||||
|
||||
|
||||
@@ -8,3 +8,6 @@ logging.level.org.apache.kafka=ERROR
|
||||
|
||||
# Auto Prefix Namespace
|
||||
mcp.namespace=sms
|
||||
|
||||
# API 보안 키 설정
|
||||
mcp.security.tenant-domains.TESTER-DEV=ALL
|
||||
|
||||
Reference in New Issue
Block a user