supplier/amadeus/
├── application/
│ └── AmadeusQueueService.kt # 큐 관리 서비스
├── infrastructure/
│ └── AmadeusClient.kt # SOAP API 클라이언트
├── interfaces/controller/
│ └── internals/
│ └── AmadeusQueueController.kt # 큐 API 엔드포인트
└── support/model/
├── QueuePnrInfo.kt # 큐 PNR 정보
└── QueueCount.kt # 큐 카운트 정보
2. 핵심 비즈니스 로직
2.1 큐 조회 프로세스
flowchart TD
A[큐 조회 요청] --> B[Offline OID 조회]
B --> C[병렬 큐 처리]
C --> D[Queue 1 조회]
C --> E[Queue 7 조회]
D --> F[큐 카운트 조회]
E --> G[큐 카운트 조회]
F --> H{카테고리 필터링}
H -->|Queue 1| I[카테고리 1, 6만]
H -->|Queue 7| J[전체 카테고리]
I --> K[카테고리별 PNR 조회]
J --> K
K --> L{최대 250개 제한}
L --> M[PNR 목록 반환]
L --> N[초과 시 250개만]
M --> O[전체 결과 병합]
N --> O
style H fill:#E8B4B8,stroke:#333,stroke-width:2px,color:#000
style L fill:#F39C9C,stroke:#333,stroke-width:2px,color:#000
// AmadeusQueueService.kt:24-26companion object { val TARGET_QUEUE_NUMBERS = listOf("1", "7")}
Queue 1: 일반 처리 큐
Queue 7: 특별 처리 큐
2.3 카테고리 필터링
2.3.1 큐 번호별 필터링 로직
// AmadeusQueueService.kt:67-72private fun List<QueueCount>.filterQueueCountsByCategory(queueNumber: String): List<QueueCount> { return when (queueNumber) { "1" -> this.filter { it.itemNumber in listOf("1", "6") } // Queue 1은 카테고리 1, 6만 else -> this // 나머지 큐는 전체 카테고리 }}
2.3.2 필터링 이유
Queue 1, Category 1: 일반 예약 처리 대기
Queue 1, Category 6: 특별 처리 대기
기타 카테고리: 처리 불필요 (NDC, 내부 시스템 등)
flowchart LR
A[Queue 1 카운트] --> B{카테고리 확인}
B -->|1| C[일반 처리]
B -->|6| D[특별 처리]
B -->|기타| E[필터링 제외]
C --> F[PNR 조회]
D --> F
E --> G[무시]
style B fill:#E8B4B8,stroke:#333,stroke-width:2px,color:#000
flowchart TD
A[제거 요청] --> B[요청 그룹화]
B --> C{동일 큐/카테고리?}
C -->|Yes| D[일괄 제거]
C -->|No| E[개별 제거]
D --> F[removePnrsInQueue]
E --> F
F --> G{성공?}
G -->|Yes| H[true 반환]
G -->|No| I[재시도]
I --> J{3회 시도?}
J -->|No| F
J -->|Yes| K[Slack 알림]
K --> L[false 반환]
style C fill:#E8B4B8,stroke:#333,stroke-width:2px,color:#000
style G fill:#F39C9C,stroke:#333,stroke-width:2px,color:#000
style J fill:#A8D5BA,stroke:#333,stroke-width:2px,color:#000
// AmadeusQueueController.kt:23-37@PutMappingfun remove(@RequestBody requests: List<QueueRemoveRequest>): ResponseEntity<QueueRemoveView> { // 동일한 큐/카테고리/시간모드로 그룹화 val result = requests.groupBy { Triple(it.queueNumber, it.category, it.timeMode) }.map { (key, request) -> val (queueNumber, category, timeMode) = key amadeusQueueService.remove( queueNumber = queueNumber, pnrs = request.map { it.pnr }, itemNumber = category!!, timeMode = timeMode ) }.all { it } // 모든 제거 작업이 성공해야 true return ResponseEntity.ok(QueueRemoveView.of(result = result))}
6. 병렬 처리 전략
6.1 큐 병렬 조회
// AmadeusQueueService.kt:34-59withBlocking(Dispatchers.IO) { TARGET_QUEUE_NUMBERS.pmap { originQueueNumber -> // 병렬 처리 val queueCounts = amadeusClient.getPnrCountsInQueue(...) if (queueCounts.isNotEmpty()) { queueCounts.flatMap { queueCount -> amadeusClient.getPnrsInQueue(...) } } else { emptyList() } }.getOrEmpty()}
6.2 병렬 처리 플로우
graph TD
A[getQueuePnrs 시작] --> B[pmap 병렬 처리]
B --> C[Queue 1 스레드]
B --> D[Queue 7 스레드]
C --> E[Queue 1 카운트 조회]
D --> F[Queue 7 카운트 조회]
E --> G[Queue 1 PNR 조회]
F --> H[Queue 7 PNR 조회]
G --> I[결과 병합]
H --> I
I --> J[전체 PNR 목록]
style B fill:#E8B4B8,stroke:#333,stroke-width:2px,color:#000
style I fill:#F39C9C,stroke:#333,stroke-width:2px,color:#000