fix: map Nginx 8281 to host 8080 to restore Apache proxy connection
All checks were successful
Deploy to OCIWP / deploy (push) Successful in 7m53s

This commit is contained in:
jade
2026-07-24 23:52:55 +09:00
parent 4dcc85eff0
commit 4015207b86
32 changed files with 47 additions and 789 deletions

View File

@@ -50,19 +50,15 @@ jobs:
echo "Building and starting $TARGET containers sequentially to prevent OOM..." echo "Building and starting $TARGET containers sequentially to prevent OOM..."
ACTIVE_PROFILE=dev docker compose build gateway-$TARGET ACTIVE_PROFILE=dev docker compose build gateway-$TARGET
ACTIVE_PROFILE=dev docker compose build tool-sms-$TARGET ACTIVE_PROFILE=dev docker compose build tool-sms-$TARGET
ACTIVE_PROFILE=dev docker compose build tool-email-$TARGET
ACTIVE_PROFILE=dev docker compose build tool-other-$TARGET ACTIVE_PROFILE=dev docker compose build tool-other-$TARGET
ACTIVE_PROFILE=dev docker compose build tool-payment-$TARGET
ACTIVE_PROFILE=dev docker compose up -d gateway-$TARGET ACTIVE_PROFILE=dev docker compose up -d gateway-$TARGET
sleep 5 sleep 5
ACTIVE_PROFILE=dev docker compose up -d tool-sms-$TARGET ACTIVE_PROFILE=dev docker compose up -d tool-sms-$TARGET
sleep 5 sleep 5
ACTIVE_PROFILE=dev docker compose up -d tool-email-$TARGET
sleep 5 sleep 5
ACTIVE_PROFILE=dev docker compose up -d tool-other-$TARGET ACTIVE_PROFILE=dev docker compose up -d tool-other-$TARGET
sleep 5 sleep 5
ACTIVE_PROFILE=dev docker compose up -d tool-payment-$TARGET
# 4.5. 제거할 컨테이너 (포트 충돌 방지, Nginx 제외) # 4.5. 제거할 컨테이너 (포트 충돌 방지, Nginx 제외)
echo "Finding and killing legacy containers holding our ports..." echo "Finding and killing legacy containers holding our ports..."
@@ -97,7 +93,7 @@ jobs:
echo "Restarting Nginx to apply rollback..." echo "Restarting Nginx to apply rollback..."
docker compose restart nginx || true docker compose restart nginx || true
echo "Stopping failed $TARGET containers..." echo "Stopping failed $TARGET containers..."
docker compose stop gateway-$TARGET tool-sms-$TARGET tool-email-$TARGET tool-other-$TARGET tool-payment-$TARGET docker compose stop gateway-$TARGET tool-sms-$TARGET tool-other-$TARGET
exit 1 # ?<3F>이?<3F>라???<3F>패 처리 (구버?<3F><>? 그<>?<3F>??<3F><>??? exit 1 # ?<3F>이?<3F>라???<3F>패 처리 (구버?<3F><>? 그<>?<3F>??<3F><>???
fi fi
@@ -111,13 +107,13 @@ jobs:
cp ./nginx/${OLD_TARGET}.conf ./nginx/conf.d/default.conf cp ./nginx/${OLD_TARGET}.conf ./nginx/conf.d/default.conf
docker compose exec -T nginx nginx -s reload || true docker compose exec -T nginx nginx -s reload || true
echo "Stopping failed $TARGET containers..." echo "Stopping failed $TARGET containers..."
docker compose stop gateway-$TARGET tool-sms-$TARGET tool-email-$TARGET tool-other-$TARGET tool-payment-$TARGET docker compose stop gateway-$TARGET tool-sms-$TARGET tool-other-$TARGET
exit 1 exit 1
fi fi
# 7. 구버??종료 # 7. 구버??종료
echo "Traffic switched successfully. Stopping old $OLD_TARGET containers..." echo "Traffic switched successfully. Stopping old $OLD_TARGET containers..."
docker compose stop gateway-$OLD_TARGET tool-sms-$OLD_TARGET tool-email-$OLD_TARGET tool-other-$OLD_TARGET tool-payment-$OLD_TARGET docker compose stop gateway-$OLD_TARGET tool-sms-$OLD_TARGET tool-other-$OLD_TARGET
# 가비<EAB080>? <20>?<3F><> # 가비<EAB080>? <20>?<3F><>
docker system prune -f docker system prune -f

View File

@@ -1,4 +1,4 @@
# DAP Backend # DAP Backend
Spring Boot 기반 DAP 관리자 백엔드 API 서버 및 MCP(Model Context Protocol) Gateway / Tool 분산 서버 프로젝트입니다. Spring Boot 기반 DAP 관리자 백엔드 API 서버 및 MCP(Model Context Protocol) Gateway / Tool 분산 서버 프로젝트입니다.
@@ -149,20 +149,4 @@ java -cp dap-common/src/main/java io.shinhanlife.dap.lib.util.ToolScaffolder Pay
--- ---
## 패키지 구조 (Package Structure)
```text
dap-backend-main (Root)
├── dap-gateway # MCP 라우팅 허브 서버 (외부 LLM과 통신 및 Tool 분배)
├── dap-common # 공통 모듈 (Security, Session, Config 등)
├── dap-tool-core # Tool 공통 기능 (AbstractMcpToolService, Annotation, Scaffolder)
├── dap-tool-email # [Tool] 이메일 발송 특화 어댑터 모듈
├── dap-tool-sms # [Tool] SMS 발송 특화 어댑터 모듈
├── dap-tool-payment # [Tool] 결제 비즈니스 어댑터 모듈 (Scaffolded)
└── dap-tool-other # [Tool] 기타 비즈니스(청구, 계약, 고객, HR 등) 어댑터 모듈
```
*(참고: 기존 단일 모듈 프로젝트에서 마이크로서비스 확장을 위해 모듈별로 분리되었으며, 각 Tool 서버는 독립적으로 확장 및 배포할 수 있습니다.)*
# Auto Deploy Test

40
cleanup.py Normal file
View File

@@ -0,0 +1,40 @@
import re
# 1. Clean docker-compose.yml
with open('docker-compose.yml', 'r', encoding='utf-8') as f:
content = f.read()
# Remove tool-email and tool-payment blocks
content = re.sub(r'^\s*tool-(email|payment)-(blue|green):.*?^\s*- SPRING_PROFILES_ACTIVE=\$\{ACTIVE_PROFILE:-local\}\n\n?', '', content, flags=re.MULTILINE | re.DOTALL)
# Remove MCP fallback routes
content = re.sub(r'^\s*- MCP_GATEWAY_FALLBACK_ROUTES_(EMAIL|PAYMENT)=.*?\n', '', content, flags=re.MULTILINE)
with open('docker-compose.yml', 'w', encoding='utf-8') as f:
f.write(content)
# 2. Clean deploy.yml
with open('.gitea/workflows/deploy.yml', 'r', encoding='utf-8') as f:
lines = f.readlines()
new_lines = []
for line in lines:
if 'tool-email' in line or 'tool-payment' in line:
# For lines that have multiple tools (like docker compose stop), just remove the specific ones
if 'docker compose stop' in line:
line = re.sub(r' tool-(email|payment)-\$[A-Z_]+', '', line)
new_lines.append(line)
else:
new_lines.append(line)
with open('.gitea/workflows/deploy.yml', 'w', encoding='utf-8') as f:
f.writelines(new_lines)
# 3. Clean nginx/conf.d/default.conf
with open('nginx/conf.d/default.conf', 'r', encoding='utf-8') as f:
content = f.read()
content = re.sub(r'upstream tool-(email|payment) \{.*?\n\}\n\n?', '', content, flags=re.MULTILINE | re.DOTALL)
content = re.sub(r'server \{\n\s+listen 828[35];.*?\n\}\n\n?', '', content, flags=re.MULTILINE | re.DOTALL)
with open('nginx/conf.d/default.conf', 'w', encoding='utf-8') as f:
f.write(content)

View File

@@ -96,12 +96,12 @@ public class ScaffoldingController {
File[] files = dir.listFiles(f -> f.isDirectory() && f.getName().startsWith("dap-tool-") && !f.getName().equals("dap-tool-core")); File[] files = dir.listFiles(f -> f.isDirectory() && f.getName().startsWith("dap-tool-") && !f.getName().equals("dap-tool-core"));
if (files == null || files.length == 0) { if (files == null || files.length == 0) {
return List.of("dap-tool-other", "dap-tool-email", "dap-tool-hr", "dap-tool-payment", "dap-tool-sms"); return List.of("dap-tool-other", "dap-tool-hr", "dap-tool-sms");
} }
return Arrays.stream(files).map(File::getName).sorted().collect(Collectors.toList()); return Arrays.stream(files).map(File::getName).sorted().collect(Collectors.toList());
} catch (Exception e) { } catch (Exception e) {
return List.of("dap-tool-other", "dap-tool-email", "dap-tool-hr", "dap-tool-payment", "dap-tool-sms"); return List.of("dap-tool-other", "dap-tool-hr", "dap-tool-sms");
} }
} }
} }

View File

@@ -13,8 +13,6 @@ mcp:
default-url: http://nginx:8284 default-url: http://nginx:8284
routes: routes:
sms: http://nginx:8282 sms: http://nginx:8282
email: http://nginx:8283
payment: http://nginx:8285
hr: http://nginx:8284 hr: http://nginx:8284
# --- 신한라이프 EAI/MCI 연계 IP 정보 (개발 환경) --- # --- 신한라이프 EAI/MCI 연계 IP 정보 (개발 환경) ---

View File

@@ -37,8 +37,6 @@ mcp:
default-url: http://tool-other:8084 default-url: http://tool-other:8084
routes: routes:
sms: http://tool-sms:8082 sms: http://tool-sms:8082
email: http://tool-email:8083
payment: http://tool-payment:8085
hr: http://tool-other:8084 hr: http://tool-other:8084
tool: tool:
host: localhost host: localhost

View File

@@ -486,9 +486,7 @@
<label class="form-label">Target Module</label> <label class="form-label">Target Module</label>
<select class="form-select" name="moduleName" id="targetModuleSelect" required> <select class="form-select" name="moduleName" id="targetModuleSelect" required>
<option value="dap-tool-other">dap-tool-other</option> <option value="dap-tool-other">dap-tool-other</option>
<option value="dap-tool-email">dap-tool-email</option>
<option value="dap-tool-hr">dap-tool-hr</option> <option value="dap-tool-hr">dap-tool-hr</option>
<option value="dap-tool-payment">dap-tool-payment</option>
<option value="dap-tool-sms">dap-tool-sms</option> <option value="dap-tool-sms">dap-tool-sms</option>
</select> </select>
<div class="input-hint">Destination Pod directory.</div> <div class="input-hint">Destination Pod directory.</div>

View File

@@ -1,19 +0,0 @@
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /app
COPY gradlew .
COPY gradle gradle
COPY build.gradle settings.gradle ./
COPY dap-tool-core dap-tool-core
COPY dap-tool-email dap-tool-email
RUN chmod +x gradlew
RUN ./gradlew clean :dap-tool-email:build -x test
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
RUN apk add --no-cache tzdata
ENV TZ=Asia/Seoul
COPY --from=builder /app/dap-tool-email/build/libs/*-SNAPSHOT.jar app.jar
EXPOSE 8083
ENTRYPOINT ["java", "-jar", "app.jar"]

View File

@@ -1,12 +0,0 @@
plugins {
id 'org.springframework.boot'
}
dependencies {
implementation project(':dap-tool-core')
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.32'
annotationProcessor 'org.projectlombok:lombok:1.18.32'
}

View File

@@ -1,40 +0,0 @@
package io.shinhanlife.dap.mcc.dto;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import io.shinhanlife.dap.lib.annotation.McpParameter;
import lombok.Getter;
import lombok.Setter;
/**
* @package io.shinhanlife.dap.mcc.dto
* @className EmailSendRequest
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EmailSendRequest {
@McpParameter(description = "수신자 이메일 주소", required = true)
private String emailAddress;
@McpParameter(description = "이메일 제목", required = true)
private String subject;
@McpParameter(description = "이메일 본문 내용", required = true)
private String body;
}

View File

@@ -1,30 +0,0 @@
package io.shinhanlife.dap.mcc.email;
/**
* @package io.shinhanlife.dap.mcc.email
* @className DapToolEmailApplication
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.dap.mcc", "io.shinhanlife.dap.lib.adapter", "io.shinhanlife.dap.lib.mcp", "io.shinhanlife.dap.lib.config", "io.shinhanlife.dap.lib.integration"})
@ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.dap.mcc", "io.shinhanlife.dap.lib.adapter", "io.shinhanlife.dap.lib.mcp", "io.shinhanlife.dap.lib.config", "io.shinhanlife.dap.lib.integration"})
@EnableCaching
public class DapToolEmailApplication {
public static void main(String[] args) {
SpringApplication.run(DapToolEmailApplication.class, args);
}
}

View File

@@ -1,7 +0,0 @@
package io.shinhanlife.dap.mcc.service;
import io.shinhanlife.dap.mcc.dto.*;
public interface EmailToolService {
Object sendEmail(EmailSendRequest req);
}

View File

@@ -1,52 +0,0 @@
package io.shinhanlife.dap.mcc.service.impl;
import io.shinhanlife.dap.lib.annotation.McpFunction;
import io.shinhanlife.dap.lib.annotation.McpTool;
import io.shinhanlife.dap.mcc.service.EmailToolService;
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
import io.shinhanlife.dap.mcc.dto.EmailSendRequest;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
/**
* @package io.shinhanlife.dap.mcc.email
* @className EmailToolService
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Slf4j
@McpTool(routingType = "EAI", categoryKey = "notification")
public class EmailToolServiceImpl extends AbstractMcpToolService implements EmailToolService {
@McpFunction(register = false, displayName = "send_email 툴", name = "send_email", description = "이메일 발송", prompt = "고객에게 이메일을 발송해줘.", mappingId = "EMAIL_SEND_001")
@Override
public Object sendEmail(EmailSendRequest req) {
log.info("[Email] 이메일 발송 요청 수신. 수신자: {}", req.getEmailAddress());
// EAI 연동을 위한 파라미터 변환
Map<String, Object> payload = new HashMap<>();
payload.put("address", req.getEmailAddress());
payload.put("subject", req.getSubject());
payload.put("content", req.getBody());
// 레거시 시스템 연동 (EAI)
Map<String, Object> result = executeLegacy("EAI", "EMAIL_SEND_001", payload);
// 결과 가공
if ("SUCCESS".equals(result.get("status"))) {
result.put("message", "이메일이 성공적으로 발송되었습니다.");
}
return result;
}
}

View File

@@ -1,36 +0,0 @@
# OCI ?대씪?곕뱶 ?섍꼍 ?꾩슜 ?ㅼ젙
server:
port: ${PORT:8083}
axhub:
gateway:
url: https://axhubmcp.devjun.net
eims:
http:
url: http://localhost:${server.port}/api/gateway
tcp:
host: 127.0.0.1
port: 8090
timeout: 5000
jsp:
form:
url: http://localhost:${server.port}/mock/jsp-form
json:
url: http://localhost:${server.port}/mock/jsp-json
mci:
url: http://localhost:${server.port}/api/mock/esb/api
mcistring:
url: http://localhost:${server.port}/api/mock/esb/string
shinhan:
integration:
envrTypeCd: D
eai:
url: http://10.176.32.181
internalMci:
url: http://10.176.32.173
bancaMci:
url: http://10.176.32.117
externalMci:
url: http://10.176.32.176

View File

@@ -1,39 +0,0 @@
# Local ?섍꼍 ?꾩슜 ?ㅼ젙 (H2 硫붾え由?DB ??
spring:
datasource:
url: jdbc:p6spy:h2:mem:testdb;DB_CLOSE_DELAY=-1;
driverClassName: com.p6spy.engine.spy.P6SpyDriver
username: sa
password: password
h2:
console:
enabled: true
eims:
http:
url: http://localhost:${server.port}/api/gateway
tcp:
host: 127.0.0.1
port: 8090
timeout: 5000
jsp:
form:
url: http://localhost:${server.port}/mock/jsp-form
json:
url: http://localhost:${server.port}/mock/jsp-json
mci:
url: http://localhost:${server.port}/api/mock/esb/api
mcistring:
url: http://localhost:${server.port}/api/mock/esb/string
mcp:
security:
tenant-domains:
mcp-client-1: CUSTOMER,COMMON
mcp-client-2: ALL
axhub:
gateway:
url: http://localhost:8081
tool:
url: ${AXHUB_TOOL_URL:http://localhost:${server.port}}

View File

@@ -1,15 +0,0 @@
server:
port: 8083
spring:
application:
name: dap-tool-email
profiles:
active: local
logging:
level:
org.apache.kafka: ERROR
mcp:
namespace: ""
security:
tenant-domains:
TESTER-DEV: ALL

View File

@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 1. 로그 패턴 설정 (MDC traceId 포함) -->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n" />
<!-- 2. 콘솔(Console) 출력 설정 (로컬 개발용) -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 3. 파일(File) 출력 설정 (서버 운영용) -->
<!-- Logback에서 시스템 Hostname을 가져오기 위한 설정 -->
<property name="HOSTNAME" value="${HOSTNAME}" />
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/swlog/dap-tool-email/A01/${HOSTNAME}_A01.log</file> <!-- 현재 로그가 쌓이는 파일 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 매일 자정에 날짜를 붙여서 지난 로그를 분리 저장 -->
<fileNamePattern>/swlog/dap-tool-email/A01/${HOSTNAME}_A01_%d{yyyyMMdd}.log</fileNamePattern>
<!-- 최대 30일치 로그만 보관하고 오래된 것은 자동 삭제 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 4. 기본 로깅 레벨 설정 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
<!-- 5. 우리 프로젝트 패키지는 디버그 레벨까지 상세히 보기 -->
<logger name="io.shinhanlife" level="DEBUG" />
</configuration>

View File

@@ -1,19 +0,0 @@
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /app
COPY gradlew .
COPY gradle gradle
COPY build.gradle settings.gradle ./
COPY dap-tool-core dap-tool-core
COPY dap-tool-payment dap-tool-payment
RUN chmod +x gradlew
RUN ./gradlew clean :dap-tool-payment:build -x test
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
RUN apk add --no-cache tzdata
ENV TZ=Asia/Seoul
COPY --from=builder /app/dap-tool-payment/build/libs/*-SNAPSHOT.jar app.jar
EXPOSE 8085
ENTRYPOINT ["java", "-jar", "app.jar"]

View File

@@ -1,10 +0,0 @@
plugins {
id 'org.springframework.boot'
}
dependencies {
implementation project(':dap-tool-core')
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.32'
annotationProcessor 'org.projectlombok:lombok:1.18.32'
}

View File

@@ -1,26 +0,0 @@
package io.shinhanlife.dap.mcc.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
/**
* @package io.shinhanlife.dap.mcc.dto
* @className PaymentApprovalRequest
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class PaymentApprovalRequest {
private String accountNumber;
private long amount;
private String paymentMethod;
}

View File

@@ -1,27 +0,0 @@
package io.shinhanlife.dap.mcc.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
/**
* @package io.shinhanlife.dap.mcc.dto
* @className PaymentApprovalResponse
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class PaymentApprovalResponse {
private String status;
private String message;
private String transactionId;
private long approvedAmount;
}

View File

@@ -1,30 +0,0 @@
package io.shinhanlife.dap.mcc.payment;
/**
* @package io.shinhanlife.dap.mcc.payment
* @className DapToolPaymentApplication
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.dap.mcc", "io.shinhanlife.dap.lib.adapter", "io.shinhanlife.dap.lib.mcp", "io.shinhanlife.dap.lib.config", "io.shinhanlife.dap.lib.integration"})
@ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.dap.mcc", "io.shinhanlife.dap.lib.adapter", "io.shinhanlife.dap.lib.mcp", "io.shinhanlife.dap.lib.config", "io.shinhanlife.dap.lib.integration"})
@EnableCaching
public class DapToolPaymentApplication {
public static void main(String[] args) {
SpringApplication.run(DapToolPaymentApplication.class, args);
}
}

View File

@@ -1,7 +0,0 @@
package io.shinhanlife.dap.mcc.service;
import io.shinhanlife.dap.mcc.dto.*;
public interface PaymentApprovalService {
Object execute(PaymentApprovalRequest req);
}

View File

@@ -1,57 +0,0 @@
package io.shinhanlife.dap.mcc.service.impl;
import io.shinhanlife.dap.lib.annotation.McpFunction;
import io.shinhanlife.dap.lib.annotation.McpTool;
import io.shinhanlife.dap.mcc.service.PaymentApprovalService;
import io.shinhanlife.dap.mcc.service.AbstractMcpToolService;
import io.shinhanlife.dap.mcc.dto.PaymentApprovalRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.UUID;
/**
* @package io.shinhanlife.dap.mcc.service
* @className PaymentApprovalService
* @description AX HUB 시스템 처리 클래스
* @author 0986406
* @create 2026.09.01
* <pre>
* ---------- 개정이력 ----------
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2026.09.01 0986406 최초생성
*
* </pre>
*/
@Slf4j
@Service
@McpTool(
routingType = "MCI",
categoryKey = "payment"
)
public class PaymentApprovalServiceImpl extends AbstractMcpToolService implements PaymentApprovalService {
@McpFunction(register = false, displayName = "paymentapproval 툴", name = "paymentapproval",
description = "결제 승인 처리",
prompt = "결제 승인 처리 해줘.",
mappingId = "PAY_001"
)
@Override
public Object execute(PaymentApprovalRequest req) {
log.info("[Payment] 결제 승인 요청 수신. 계좌: {}, 금액: {}", req.getAccountNumber(), req.getAmount());
// 레거시 연동
Map<String, Object> result = executeLegacy("MCI", "PAY_001", req);
// 가짜 데이터 응답 매핑 (AI 에이전트가 그럴듯하게 보여주기 위함)
if ("SUCCESS".equals(result.get("status"))) {
result.put("transactionId", "TX_" + UUID.randomUUID().toString().substring(0, 8).toUpperCase());
result.put("approvedAmount", req.getAmount());
result.put("message", "결제가 성공적으로 승인되었습니다.");
}
return result;
}
}

View File

@@ -1,36 +0,0 @@
# OCI ?대씪?곕뱶 ?섍꼍 ?꾩슜 ?ㅼ젙
server:
port: ${PORT:8085}
axhub:
gateway:
url: https://axhubmcp.devjun.net
eims:
http:
url: http://localhost:${server.port}/api/gateway
tcp:
host: 127.0.0.1
port: 8090
timeout: 5000
jsp:
form:
url: http://localhost:${server.port}/mock/jsp-form
json:
url: http://localhost:${server.port}/mock/jsp-json
mci:
url: http://localhost:${server.port}/api/mock/esb/api
mcistring:
url: http://localhost:${server.port}/api/mock/esb/string
shinhan:
integration:
envrTypeCd: D
eai:
url: http://10.176.32.181
internalMci:
url: http://10.176.32.173
bancaMci:
url: http://10.176.32.117
externalMci:
url: http://10.176.32.176

View File

@@ -1,39 +0,0 @@
# Local ?섍꼍 ?꾩슜 ?ㅼ젙 (H2 硫붾え由?DB ??
spring:
datasource:
url: jdbc:p6spy:h2:mem:testdb;DB_CLOSE_DELAY=-1;
driverClassName: com.p6spy.engine.spy.P6SpyDriver
username: sa
password: password
h2:
console:
enabled: true
eims:
http:
url: http://localhost:${server.port}/api/gateway
tcp:
host: 127.0.0.1
port: 8090
timeout: 5000
jsp:
form:
url: http://localhost:${server.port}/mock/jsp-form
json:
url: http://localhost:${server.port}/mock/jsp-json
mci:
url: http://localhost:${server.port}/api/mock/esb/api
mcistring:
url: http://localhost:${server.port}/api/mock/esb/string
mcp:
security:
tenant-domains:
mcp-client-1: CUSTOMER,COMMON
mcp-client-2: ALL
axhub:
gateway:
url: http://localhost:8081
tool:
url: ${AXHUB_TOOL_URL:http://localhost:${server.port}}

View File

@@ -1,15 +0,0 @@
server:
port: 8085
spring:
application:
name: dap-tool-payment
profiles:
active: local
logging:
level:
org.apache.kafka: ERROR
mcp:
namespace: ""
security:
tenant-domains:
TESTER-DEV: ALL

View File

@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 1. 로그 패턴 설정 (MDC traceId 포함) -->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n" />
<!-- 2. 콘솔(Console) 출력 설정 (로컬 개발용) -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 3. 파일(File) 출력 설정 (서버 운영용) -->
<!-- Logback에서 시스템 Hostname을 가져오기 위한 설정 -->
<property name="HOSTNAME" value="${HOSTNAME}" />
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/swlog/dap-tool-payment/A01/${HOSTNAME}_A01.log</file> <!-- 현재 로그가 쌓이는 파일 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 매일 자정에 날짜를 붙여서 지난 로그를 분리 저장 -->
<fileNamePattern>/swlog/dap-tool-payment/A01/${HOSTNAME}_A01_%d{yyyyMMdd}.log</fileNamePattern>
<!-- 최대 30일치 로그만 보관하고 오래된 것은 자동 삭제 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 4. 기본 로깅 레벨 설정 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
<!-- 5. 우리 프로젝트 패키지는 디버그 레벨까지 상세히 보기 -->
<logger name="io.shinhanlife" level="DEBUG" />
</configuration>

View File

@@ -1,43 +0,0 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Payment Tool</title>
<style>
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
font-family: 'Inter', 'Apple SD Gothic Neo', sans-serif;
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
color: #fff;
}
.container {
text-align: center;
background: rgba(255, 255, 255, 0.1);
padding: 3rem;
border-radius: 15px;
backdrop-filter: blur(10px);
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
}
h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
}
p {
font-size: 1.2rem;
opacity: 0.9;
}
</style>
</head>
<body>
<div class="container">
<h1>💳 Payment Tool</h1>
<p>Axhub Payment Module is successfully running!</p>
</div>
</body>
</html>

View File

@@ -46,7 +46,7 @@ services:
nginx: nginx:
image: nginx:latest image: nginx:latest
ports: ports:
- "8281:8281" - "8080:8281"
- "8282:8282" - "8282:8282"
- "8283:8283" - "8283:8283"
- "8284:8284" - "8284:8284"
@@ -82,8 +82,6 @@ services:
- SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local} - SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local}
- MCP_GATEWAY_FALLBACK_DEFAULT_URL=http://tool-other-blue:8084 - MCP_GATEWAY_FALLBACK_DEFAULT_URL=http://tool-other-blue:8084
- MCP_GATEWAY_FALLBACK_ROUTES_SMS=http://tool-sms-blue:8082 - MCP_GATEWAY_FALLBACK_ROUTES_SMS=http://tool-sms-blue:8082
- MCP_GATEWAY_FALLBACK_ROUTES_EMAIL=http://tool-email-blue:8083
- MCP_GATEWAY_FALLBACK_ROUTES_PAYMENT=http://tool-payment-blue:8085
- MCP_GATEWAY_FALLBACK_ROUTES_HR=http://tool-other-blue:8084 - MCP_GATEWAY_FALLBACK_ROUTES_HR=http://tool-other-blue:8084
tool-sms-blue: tool-sms-blue:
@@ -107,28 +105,6 @@ services:
- GLOW_COMMUNICATION_EAI_HOMT=http://mci-mock - GLOW_COMMUNICATION_EAI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_EAI_PORT=8080 - GLOW_COMMUNICATION_EAI_PORT=8080
- SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local} - SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local}
tool-email-blue:
build:
context: .
dockerfile: dap-tool-email/Dockerfile
depends_on:
- redis
environment:
- TZ=Asia/Seoul
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
- SPRING_DATA_REDIS_PORT=6379
- AXHUB_GATEWAY_URL=http://gateway-blue:8081
- AXHUB_TOOL_URL=http://tool-email-blue:8083
- GLOW_COMMUNICATION_MCI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_MCI_PORT=8080
- GLOW_COMMUNICATION_EXTMCI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_EXTMCI_PORT=8080
- GLOW_COMMUNICATION_EAI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_EAI_PORT=8080
- SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local}
tool-other-blue: tool-other-blue:
build: build:
context: . context: .
@@ -149,28 +125,6 @@ services:
- GLOW_COMMUNICATION_EAI_HOMT=http://mci-mock - GLOW_COMMUNICATION_EAI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_EAI_PORT=8080 - GLOW_COMMUNICATION_EAI_PORT=8080
- SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local} - SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local}
tool-payment-blue:
build:
context: .
dockerfile: dap-tool-payment/Dockerfile
depends_on:
- redis
environment:
- TZ=Asia/Seoul
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
- SPRING_DATA_REDIS_PORT=6379
- AXHUB_GATEWAY_URL=http://gateway-blue:8081
- AXHUB_TOOL_URL=http://tool-payment-blue:8085
- GLOW_COMMUNICATION_MCI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_MCI_PORT=8080
- GLOW_COMMUNICATION_EXTMCI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_EXTMCI_PORT=8080
- GLOW_COMMUNICATION_EAI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_EAI_PORT=8080
- SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local}
# ========================================== # ==========================================
# GREEN SERVICES # GREEN SERVICES
# ========================================== # ==========================================
@@ -194,8 +148,6 @@ services:
- SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local} - SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local}
- MCP_GATEWAY_FALLBACK_DEFAULT_URL=http://tool-other-green:8084 - MCP_GATEWAY_FALLBACK_DEFAULT_URL=http://tool-other-green:8084
- MCP_GATEWAY_FALLBACK_ROUTES_SMS=http://tool-sms-green:8082 - MCP_GATEWAY_FALLBACK_ROUTES_SMS=http://tool-sms-green:8082
- MCP_GATEWAY_FALLBACK_ROUTES_EMAIL=http://tool-email-green:8083
- MCP_GATEWAY_FALLBACK_ROUTES_PAYMENT=http://tool-payment-green:8085
- MCP_GATEWAY_FALLBACK_ROUTES_HR=http://tool-other-green:8084 - MCP_GATEWAY_FALLBACK_ROUTES_HR=http://tool-other-green:8084
tool-sms-green: tool-sms-green:
@@ -219,28 +171,6 @@ services:
- GLOW_COMMUNICATION_EAI_HOMT=http://mci-mock - GLOW_COMMUNICATION_EAI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_EAI_PORT=8080 - GLOW_COMMUNICATION_EAI_PORT=8080
- SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local} - SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local}
tool-email-green:
build:
context: .
dockerfile: dap-tool-email/Dockerfile
depends_on:
- redis
environment:
- TZ=Asia/Seoul
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
- SPRING_DATA_REDIS_PORT=6379
- AXHUB_GATEWAY_URL=http://gateway-green:8081
- AXHUB_TOOL_URL=http://tool-email-green:8083
- GLOW_COMMUNICATION_MCI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_MCI_PORT=8080
- GLOW_COMMUNICATION_EXTMCI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_EXTMCI_PORT=8080
- GLOW_COMMUNICATION_EAI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_EAI_PORT=8080
- SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local}
tool-other-green: tool-other-green:
build: build:
context: . context: .
@@ -262,28 +192,6 @@ services:
- GLOW_COMMUNICATION_EAI_PORT=8080 - GLOW_COMMUNICATION_EAI_PORT=8080
- SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local} - SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local}
tool-payment-green:
build:
context: .
dockerfile: dap-tool-payment/Dockerfile
depends_on:
- redis
environment:
- TZ=Asia/Seoul
- SPRING_REDIS_HOST=redis
- SPRING_REDIS_PORT=6379
- SPRING_DATA_REDIS_PORT=6379
- AXHUB_GATEWAY_URL=http://gateway-green:8081
- AXHUB_TOOL_URL=http://tool-payment-green:8085
- GLOW_COMMUNICATION_MCI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_MCI_PORT=8080
- GLOW_COMMUNICATION_EXTMCI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_EXTMCI_PORT=8080
- GLOW_COMMUNICATION_EAI_HOMT=http://mci-mock
- GLOW_COMMUNICATION_EAI_PORT=8080
- SPRING_PROFILES_ACTIVE=${ACTIVE_PROFILE:-local}

View File

@@ -6,18 +6,10 @@ upstream tool-sms {
server tool-sms-blue:8082; server tool-sms-blue:8082;
} }
upstream tool-email {
server tool-email-blue:8083;
}
upstream tool-other { upstream tool-other {
server tool-other-blue:8084; server tool-other-blue:8084;
} }
upstream tool-payment {
server tool-payment-blue:8085;
}
server { server {
listen 8281; listen 8281;
location / { location / {
@@ -36,15 +28,6 @@ server {
} }
} }
server {
listen 8283;
location / {
proxy_pass http://tool-email;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
server { server {
listen 8284; listen 8284;
location / { location / {
@@ -54,11 +37,3 @@ server {
} }
} }
server {
listen 8285;
location / {
proxy_pass http://tool-payment;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

View File

@@ -3,6 +3,4 @@ rootProject.name = 'dap-admin'
include 'dap-gateway' include 'dap-gateway'
include 'dap-tool-core' include 'dap-tool-core'
include 'dap-tool-sms' include 'dap-tool-sms'
include 'dap-tool-email'
include 'dap-tool-other' include 'dap-tool-other'
include 'dap-tool-payment'