mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2025-12-06 13:26:23 +00:00
- API-TEST-RESULT.md → test/ - content-service-integration-analysis.md → test/ - content-service-integration-test-results.md → test/ - test-kafka-integration-results.md → test/ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
505 lines
15 KiB
Markdown
505 lines
15 KiB
Markdown
# Content Service 통합 분석 보고서
|
|
|
|
**작성일**: 2025-10-30
|
|
**작성자**: Backend Developer
|
|
**테스트 환경**: 개발 환경
|
|
**서비스**: content-service (포트 8084)
|
|
|
|
---
|
|
|
|
## 1. 분석 개요
|
|
|
|
### 분석 목적
|
|
- content-service의 서비스 간 HTTP 통신 검증
|
|
- Job 관리 메커니즘 파악
|
|
- EventId 기반 데이터 조회 기능 확인
|
|
- Kafka 연동 현황 파악
|
|
|
|
### 분석 범위
|
|
- ✅ content-service API 구조 분석
|
|
- ✅ 서비스 설정 및 의존성 확인
|
|
- ✅ Kafka 연동 상태 파악
|
|
- ✅ Redis 기반 Job 관리 구조 분석
|
|
- ⏳ 실제 API 테스트 (서버 미실행으로 대기 중)
|
|
|
|
---
|
|
|
|
## 2. Content Service 아키텍처 분석
|
|
|
|
### 2.1 서비스 정보
|
|
```yaml
|
|
Service Name: content-service
|
|
Port: 8084
|
|
Context Path: /api/v1/content
|
|
Main Class: com.kt.content.ContentApplication
|
|
```
|
|
|
|
### 2.2 주요 의존성
|
|
```yaml
|
|
Infrastructure:
|
|
- PostgreSQL Database (4.217.131.139:5432)
|
|
- Redis Cache (20.214.210.71:6379)
|
|
- Azure Blob Storage (content-images)
|
|
|
|
External APIs:
|
|
- Replicate API (Stable Diffusion SDXL)
|
|
- Mock Mode: ENABLED (개발 환경)
|
|
- Model: stability-ai/sdxl
|
|
|
|
Framework:
|
|
- Spring Boot
|
|
- JPA (DDL Auto: update)
|
|
- Spring Data Redis
|
|
```
|
|
|
|
### 2.3 API 엔드포인트 구조
|
|
|
|
#### 이미지 생성 API
|
|
```http
|
|
POST /api/v1/content/images/generate
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"eventId": "string",
|
|
"eventTitle": "string",
|
|
"eventDescription": "string",
|
|
"industry": "string",
|
|
"location": "string",
|
|
"trends": ["string"],
|
|
"styles": ["SIMPLE", "TRENDY", "MODERN", "PROFESSIONAL"],
|
|
"platforms": ["INSTAGRAM", "KAKAO", "FACEBOOK"]
|
|
}
|
|
|
|
Response: 202 ACCEPTED
|
|
{
|
|
"jobId": "string",
|
|
"eventId": "string",
|
|
"status": "PENDING",
|
|
"message": "이미지 생성 작업이 시작되었습니다."
|
|
}
|
|
```
|
|
|
|
#### Job 상태 조회 API
|
|
```http
|
|
GET /api/v1/content/images/jobs/{jobId}
|
|
|
|
Response: 200 OK
|
|
{
|
|
"id": "string",
|
|
"eventId": "string",
|
|
"jobType": "IMAGE_GENERATION",
|
|
"status": "PENDING|IN_PROGRESS|COMPLETED|FAILED",
|
|
"progress": 0-100,
|
|
"resultMessage": "string",
|
|
"errorMessage": "string",
|
|
"createdAt": "timestamp",
|
|
"updatedAt": "timestamp"
|
|
}
|
|
```
|
|
|
|
#### EventId 기반 콘텐츠 조회 API
|
|
```http
|
|
GET /api/v1/content/events/{eventId}
|
|
|
|
Response: 200 OK
|
|
{
|
|
"eventId": "string",
|
|
"images": [
|
|
{
|
|
"imageId": number,
|
|
"imageUrl": "string",
|
|
"style": "string",
|
|
"platform": "string",
|
|
"prompt": "string",
|
|
"createdAt": "timestamp"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
#### 이미지 목록 조회 API
|
|
```http
|
|
GET /api/v1/content/events/{eventId}/images?style={style}&platform={platform}
|
|
|
|
Response: 200 OK
|
|
[
|
|
{
|
|
"imageId": number,
|
|
"imageUrl": "string",
|
|
"style": "string",
|
|
"platform": "string",
|
|
"prompt": "string",
|
|
"createdAt": "timestamp"
|
|
}
|
|
]
|
|
```
|
|
|
|
#### 이미지 상세 조회 API
|
|
```http
|
|
GET /api/v1/content/images/{imageId}
|
|
|
|
Response: 200 OK
|
|
{
|
|
"imageId": number,
|
|
"eventId": "string",
|
|
"imageUrl": "string",
|
|
"style": "string",
|
|
"platform": "string",
|
|
"prompt": "string",
|
|
"replicateId": "string",
|
|
"status": "string",
|
|
"createdAt": "timestamp",
|
|
"updatedAt": "timestamp"
|
|
}
|
|
```
|
|
|
|
#### 이미지 재생성 API
|
|
```http
|
|
POST /api/v1/content/images/{imageId}/regenerate
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"newPrompt": "string" (optional)
|
|
}
|
|
|
|
Response: 202 ACCEPTED
|
|
{
|
|
"jobId": "string",
|
|
"message": "이미지 재생성 작업이 시작되었습니다."
|
|
}
|
|
```
|
|
|
|
#### 이미지 삭제 API
|
|
```http
|
|
DELETE /api/v1/content/images/{imageId}
|
|
|
|
Response: 204 NO CONTENT
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Kafka 연동 분석
|
|
|
|
### 3.1 현황 파악
|
|
|
|
**❌ content-service에는 Kafka Consumer가 구현되지 않음**
|
|
|
|
**검증 방법**:
|
|
```bash
|
|
# Kafka 관련 파일 검색 결과
|
|
find content-service -name "*Kafka*" -o -name "*kafka*"
|
|
# → 결과 없음
|
|
```
|
|
|
|
**확인 사항**:
|
|
- ✅ content-service/src/main/resources/application.yml에 Kafka 설정 없음
|
|
- ✅ content-service 소스 코드에 Kafka Consumer 클래스 없음
|
|
- ✅ content-service 소스 코드에 Kafka Producer 클래스 없음
|
|
|
|
### 3.2 현재 아키텍처
|
|
|
|
```
|
|
┌─────────────────┐
|
|
│ event-service │
|
|
│ (Port 8081) │
|
|
└────────┬────────┘
|
|
│
|
|
├─── Kafka Producer ───→ Kafka Topic (image-generation-job)
|
|
│ │
|
|
│ │ (event-service Consumer가 수신)
|
|
│ ↓
|
|
│ ┌──────────────┐
|
|
│ │ event-service│
|
|
│ │ Consumer │
|
|
│ └──────────────┘
|
|
│
|
|
└─── Redis Job Data ───→ Redis Cache
|
|
↑
|
|
│
|
|
┌───────┴────────┐
|
|
│ content-service│
|
|
│ (Port 8084) │
|
|
└────────────────┘
|
|
```
|
|
|
|
**설명**:
|
|
1. event-service가 이미지 생성 요청을 받으면:
|
|
- Kafka Topic에 메시지 발행
|
|
- Redis에 Job 데이터 저장
|
|
2. event-service의 Kafka Consumer가 자신이 발행한 메시지를 수신
|
|
3. content-service는 Redis에서만 Job 데이터를 조회
|
|
|
|
### 3.3 설계 문서와의 차이점
|
|
|
|
**논리 아키텍처 설계**에서는:
|
|
```
|
|
Event-Service → Kafka → Content-Service → 이미지 생성 → Kafka → Event-Service
|
|
(Producer) (Consumer) (Producer) (Consumer)
|
|
```
|
|
|
|
**실제 구현**:
|
|
```
|
|
Event-Service → Redis ← Content-Service
|
|
↓
|
|
Kafka (메시지 발행만, content-service Consumer 없음)
|
|
↓
|
|
Event-Service Consumer (자신이 발행한 메시지 수신)
|
|
```
|
|
|
|
### 3.4 영향 분석
|
|
|
|
**장점**:
|
|
- 단순한 아키텍처 (Redis 기반 동기화)
|
|
- 구현 복잡도 낮음
|
|
- 디버깅 용이
|
|
|
|
**단점**:
|
|
- 서비스 간 결합도 증가 (Redis 공유)
|
|
- Kafka 기반 비동기 메시징의 이점 활용 불가
|
|
- 이벤트 기반 확장성 제한
|
|
|
|
**권장 사항**:
|
|
1. **옵션 A**: content-service에 Kafka Consumer 추가 구현
|
|
2. **옵션 B**: 설계 문서를 실제 구현에 맞춰 업데이트 (Redis 기반 통신)
|
|
3. **옵션 C**: 하이브리드 접근 (Redis는 Job 상태 조회용, Kafka는 이벤트 전파용)
|
|
|
|
---
|
|
|
|
## 4. Job 관리 메커니즘
|
|
|
|
### 4.1 Redis 기반 Job 관리
|
|
|
|
**JobManagementService** 분석:
|
|
```java
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
@Transactional(readOnly = true)
|
|
public class JobManagementService implements GetJobStatusUseCase {
|
|
private final JobReader jobReader;
|
|
|
|
@Override
|
|
public JobInfo execute(String jobId) {
|
|
RedisJobData jobData = jobReader.getJob(jobId)
|
|
.orElseThrow(() -> new BusinessException(ErrorCode.COMMON_001,
|
|
"Job을 찾을 수 없습니다"));
|
|
|
|
// RedisJobData → Job 도메인 변환
|
|
Job job = Job.builder()
|
|
.id(jobData.getId())
|
|
.eventId(jobData.getEventId())
|
|
.jobType(jobData.getJobType())
|
|
.status(Job.Status.valueOf(jobData.getStatus()))
|
|
.progress(jobData.getProgress())
|
|
.resultMessage(jobData.getResultMessage())
|
|
.errorMessage(jobData.getErrorMessage())
|
|
.createdAt(jobData.getCreatedAt())
|
|
.updatedAt(jobData.getUpdatedAt())
|
|
.build();
|
|
|
|
return JobInfo.from(job);
|
|
}
|
|
}
|
|
```
|
|
|
|
**특징**:
|
|
- Redis를 데이터 소스로 사용
|
|
- Job 상태는 Redis에서 읽기만 수행 (읽기 전용)
|
|
- Job 상태 업데이트는 다른 서비스(event-service)가 담당
|
|
|
|
### 4.2 Job 라이프사이클
|
|
|
|
```
|
|
1. event-service: Job 생성 → Redis에 저장 (PENDING)
|
|
2. content-service: Job 상태 조회 (Redis에서 읽기)
|
|
3. [이미지 생성 프로세스]
|
|
4. event-service: Job 상태 업데이트 → Redis (IN_PROGRESS, COMPLETED, FAILED)
|
|
5. content-service: 최신 Job 상태 조회
|
|
```
|
|
|
|
**Job 상태 값**:
|
|
- `PENDING`: 작업 대기 중
|
|
- `IN_PROGRESS`: 작업 진행 중
|
|
- `COMPLETED`: 작업 완료
|
|
- `FAILED`: 작업 실패
|
|
|
|
---
|
|
|
|
## 5. HTTP 통신 구조
|
|
|
|
### 5.1 서비스 간 통신 흐름
|
|
|
|
```
|
|
┌──────────┐ ┌──────────────┐ ┌──────────┐
|
|
│ Client │ │event-service │ │ content- │
|
|
│ │ │ │ │ service │
|
|
└─────┬────┘ └──────┬───────┘ └────┬─────┘
|
|
│ │ │
|
|
│ 1. POST /events │ │
|
|
│────────────────────────────────> │
|
|
│ │ │
|
|
│ 2. POST /events/{id}/images │ │
|
|
│────────────────────────────────> │
|
|
│ │ │
|
|
│ │ 3. [이벤트 정보는 Redis/DB 공유] │
|
|
│ │ │
|
|
│ │ │
|
|
│ 4. POST /images/generate │ │
|
|
│───────────────────────────────────────────────────────────────────>
|
|
│ │ │
|
|
│ │ 5. Redis에 Job 저장 │
|
|
│ │<────────────────────────────────│
|
|
│ │ │
|
|
│ 6. GET /images/jobs/{jobId} │ │
|
|
│───────────────────────────────────────────────────────────────────>
|
|
│ │ │
|
|
│ 7. JobInfo (from Redis) │ │
|
|
│<───────────────────────────────────────────────────────────────────
|
|
│ │ │
|
|
```
|
|
|
|
### 5.2 데이터 공유 메커니즘
|
|
|
|
**Redis 기반 데이터 공유**:
|
|
```yaml
|
|
공유 데이터:
|
|
- Job 상태 (JobId → JobData)
|
|
- Event 정보 (EventId → EventData)
|
|
|
|
데이터 흐름:
|
|
1. event-service: Redis에 데이터 쓰기
|
|
2. content-service: Redis에서 데이터 읽기
|
|
3. 실시간 동기화 (Redis TTL 설정 필요 확인)
|
|
```
|
|
|
|
---
|
|
|
|
## 6. 테스트 시나리오 준비
|
|
|
|
### 6.1 준비된 테스트 스크립트
|
|
|
|
**파일**: `test-content-service.sh`
|
|
|
|
**테스트 항목**:
|
|
1. ✅ Health Check
|
|
2. ✅ 이미지 생성 요청 (HTTP 통신)
|
|
3. ✅ Job 상태 조회 (Job 관리)
|
|
4. ✅ EventId 기반 콘텐츠 조회
|
|
5. ✅ 이미지 목록 조회
|
|
6. ✅ 이미지 필터링 (style 파라미터)
|
|
7. ✅ 이미지 재생성 요청
|
|
|
|
### 6.2 테스트 데이터
|
|
|
|
**test-image-generation.json**:
|
|
```json
|
|
{
|
|
"eventId": "EVT-str_dev_test_001-20251029220003-610158ce",
|
|
"eventTitle": "Woojin BBQ Restaurant Grand Opening Event",
|
|
"eventDescription": "Special discount event for Korean BBQ restaurant...",
|
|
"industry": "Restaurant",
|
|
"location": "Seoul",
|
|
"trends": ["Korean BBQ", "Hanwoo", "Grand Opening"],
|
|
"styles": ["SIMPLE", "TRENDY"],
|
|
"platforms": ["INSTAGRAM", "KAKAO"]
|
|
}
|
|
```
|
|
|
|
### 6.3 실행 방법
|
|
|
|
```bash
|
|
# content-service 시작 후
|
|
./test-content-service.sh
|
|
|
|
# 또는 수동 테스트
|
|
curl -X POST http://localhost:8084/api/v1/content/images/generate \
|
|
-H "Content-Type: application/json" \
|
|
-d @test-image-generation.json
|
|
```
|
|
|
|
---
|
|
|
|
## 7. 현재 상태 및 다음 단계
|
|
|
|
### 7.1 완료된 작업
|
|
- ✅ content-service API 구조 분석 완료
|
|
- ✅ Kafka 연동 현황 파악 완료
|
|
- ✅ Redis 기반 Job 관리 메커니즘 분석 완료
|
|
- ✅ 테스트 스크립트 작성 완료
|
|
|
|
### 7.2 대기 중인 작업
|
|
- ⏳ content-service 서버 시작 필요
|
|
- ⏳ HTTP 통신 실제 테스트
|
|
- ⏳ Job 관리 기능 실제 검증
|
|
- ⏳ EventId 기반 조회 기능 검증
|
|
- ⏳ 이미지 재생성 기능 테스트
|
|
|
|
### 7.3 서버 시작 방법
|
|
|
|
**IntelliJ 실행 프로파일**:
|
|
```
|
|
Run Configuration: ContentServiceApplication
|
|
Main Class: com.kt.content.ContentApplication
|
|
Port: 8084
|
|
```
|
|
|
|
**환경 변수 설정** (`.run/ContentServiceApplication.run.xml`):
|
|
```xml
|
|
<env name="SERVER_PORT" value="8084" />
|
|
<env name="REDIS_HOST" value="20.214.210.71" />
|
|
<env name="REDIS_PORT" value="6379" />
|
|
<env name="REDIS_PASSWORD" value="Hi5Jessica!" />
|
|
<env name="DB_HOST" value="4.217.131.139" />
|
|
<env name="DB_PORT" value="5432" />
|
|
<env name="DB_NAME" value="contentdb" />
|
|
<env name="DB_USERNAME" value="eventuser" />
|
|
<env name="DB_PASSWORD" value="Hi5Jessica!" />
|
|
<env name="REPLICATE_MOCK_ENABLED" value="true" />
|
|
```
|
|
|
|
### 7.4 테스트 실행 계획
|
|
|
|
**서버 시작 후 실행 순서**:
|
|
1. Health Check 확인
|
|
2. 테스트 스크립트 실행: `./test-content-service.sh`
|
|
3. 결과 분석 및 보고서 업데이트
|
|
4. 발견된 이슈 정리
|
|
|
|
---
|
|
|
|
## 8. 결론
|
|
|
|
### 8.1 핵심 발견사항
|
|
|
|
1. **Kafka 연동 미구현**
|
|
- content-service에는 Kafka Consumer가 없음
|
|
- Redis 기반 Job 관리만 사용 중
|
|
- 설계와 구현 간 차이 존재
|
|
|
|
2. **Redis 기반 아키텍처**
|
|
- 서비스 간 데이터 공유는 Redis를 통해 이루어짐
|
|
- Job 상태 관리는 Redis 중심으로 동작
|
|
- 단순하지만 서비스 간 결합도가 높음
|
|
|
|
3. **API 구조 명확성**
|
|
- RESTful API 설계가 잘 되어 있음
|
|
- 도메인 모델이 명확히 분리됨 (UseCase 패턴)
|
|
- 비동기 작업은 202 ACCEPTED로 일관되게 처리
|
|
|
|
### 8.2 권장사항
|
|
|
|
**단기 (현재 구조 유지)**:
|
|
- 설계 문서를 실제 구현에 맞춰 업데이트
|
|
- Redis 기반 통신 구조를 명시적으로 문서화
|
|
- 현재 아키텍처로 테스트 완료 후 안정화
|
|
|
|
**장기 (아키텍처 개선)**:
|
|
- content-service에 Kafka Consumer 추가 구현
|
|
- 이벤트 기반 비동기 메시징 아키텍처로 전환
|
|
- 서비스 간 결합도 감소 및 확장성 향상
|
|
|
|
---
|
|
|
|
**작성자**: Backend Developer
|
|
**검토 필요**: System Architect
|
|
**다음 작업**: content-service 서버 시작 후 테스트 실행
|