Galileo (Travelport) — 개요

module-galileo arch-supplier-module api-gds protocol-soap protocol-rest

한 줄 요약

Galileo는 Travelport GDS(시스템 코드 1G) 어댑터 모듈이다. 다른 GDS와 달리 검색만 REST(Travelport JSON API v11) 로 호출하고, 예약·발권·운임규정·큐는 SOAP(Universal API) 로 호출하는 하이브리드 프로토콜 구조다. 결제(BSP 카드/현금영수증)는 별도 KPS 게이트웨이(.aspx), 운임규정 한글 번역은 KRT를 쓴다. 소스 파일 525개로 Sabre·Amadeus 다음 3번째로 큰 공급사 모듈이다.


1. 공급사 특징: 무엇이고, 왜 이렇게 연동하는가

1-1. GDS(Global Distribution System)다

Galileo는 LCC도 FSC(개별 항공사)도 아니다. Travelport가 운영하는 GDS 브랜드로, 수백 개 항공사의 좌석·운임을 한 채널로 중개한다. 코드에서 이를 직접 확인할 수 있다.

  • 검색 엔드포인트가 특정 항공사가 아니라 카탈로그 검색 경로다. GalileoRestClient.kt:95"${...rest.endpoint}/11/air/catalog/search/catalogproductofferings"
  • 예약/발권 SOAP 엔드포인트가 항공사명이 아니라 Travelport 서비스명이다. GalileoClient.kt/AirService, /UniversalRecordService, /GdsQueueService
  • 모든 호출에 타깃 브랜치(targetBranch = branchCode)PCC(Pseudo City Code) 가 붙는다. PCC는 GDS에서 여행사 단말을 식별하는 가상 도시 코드로, GDS 연동의 전형적 특징이다. Properties.kt:421 GalileoApiProperties.pcc, GalileoSoapProperties.branchCode

GDS vs LCC 어댑터의 차이

LCC 모듈(tway·jinair·jejuair)은 개별 항공사 REST API 하나에 직접 붙는다. GDS인 Galileo는 GDS라는 중개 계층을 통해 여러 항공사를 다루므로, 항공사 식별(validatingCarrier)과 PCC·브랜치 컨텍스트가 모든 요청에 따라다닌다. 같은 GDS 계열인 Amadeus(1A), Sabre(1S)와 함께 묶어서 이해하면 좋다.

1-2. 왜 “하이브리드”인가 — REST 검색 + SOAP 예약

Travelport는 레거시 Universal API(SOAP) 와 신형 JSON/REST API(Travelport Air, v11) 를 모두 제공한다. 이 모듈은 둘을 오퍼레이션별로 골라 쓴다.

오퍼레이션프로토콜클라이언트 / 엔드포인트근거
SearchREST (JSON)GalileoRestClient/11/air/catalog/search/catalogproductofferingsGalileoRestClient.kt:76,95
Pricing / Booking / Ticketing / Void / FareRule / Divide / Retrieve / ModifySOAP (Universal API)GalileoClient/AirService, /UniversalRecordServiceGalileoClient.kt:99~800
Queue (count/list/remove)SOAPGalileoClient/GdsQueueServiceGalileoClient.kt:802~899
결제(BSP 카드 승인/취소, 현금영수증)REST/HTTP .aspxKpsPaymentClientKpsBspCardAuth.aspxKpsPaymentClient.kt:53,92,130,168
FareRule 한글 번역HTTP XML .aspxKrtClientFareRuleTransKor.aspxKrtClient.kt:36

검색은 왜 REST인가?

신형 JSON API는 브랜디드 운임(브랜드별 부가서비스/수하물 옵션)amenity 정보를 풍부하게 돌려준다. 검색 응답을 productBrandOptions 단위로 펼쳐 FareItinerary로 만드는 흐름(GalileoRestClient.kt:132~144)이 이를 보여준다. 반면 실제 PNR을 만들고 항공권을 발권하는 트랜잭션 영역은 검증된 Universal API(SOAP) 를 그대로 쓴다. 즉 “읽기는 신형, 쓰기는 레거시”의 절충이다. 자세한 프로토콜 디테일은 galileo-protocol 참고.

1-3. 비즈니스/시장 맥락 — 한국 GDS, 멀티 PCC/채널

  • 인증 단위가 PCC + 채널(channel) + 퍼널(funnel) 의 3중 매핑이다. GalileoProperties.getApiProperties(salesChannel, salesFunnel)MDCHolder에서 판매 채널/퍼널을 읽어 그에 맞는 PCC·계정을 선택한다. Properties.kt:259~269
  • 온라인 PCC / 오프라인 PCC를 분리해서 운영한다. SOAP 설정에 offline(별도 PCC·계정·브랜치)이 중첩돼 있다. Properties.kt:443~457 (GalileoSoapProperties.offline = GalileoOfflineProperties)
  • 결제·영수증을 한국형 게이트웨이(KPS)로 처리한다. BSP 카드 승인은 KpsBspCardAuth.aspx, 현금영수증 발급은 KpsCashReceiptIssue.aspx로, 한국 시장(현금영수증 의무화 등) 특화 흐름이다. KpsPaymentClient.kt:53,130
  • 운임규정 한글화: 원문 영문 운임규정을 FareRuleTransKor.aspx(KRT)로 번역한다. 국내 사용자 대상 서비스임을 드러낸다. KrtClient.kt:36

브리핑 정정 — SessionContext는 이 모듈에 없다

사전 브리핑에는 “SessionContext”가 특징으로 적혀 있으나, galileo 패키지는 물론 air-intl-adapter 소스 전체에 SessionContext 클래스/식별자가 존재하지 않는다(grep -rn "SessionContext" 결과 0건). Galileo는 명시적 세션 객체 대신 REST는 토큰을 Redis에 캐시(GALILEO_REST_TOKEN, GalileoRestClient.kt:48~73)하고, SOAP는 매 요청마다 Basic 인증(userName/password) 으로 stateless하게 호출한다. 이 점에서 stateful PNR 세션을 유지하는 Amadeus와 결정적으로 다르다. “스키마 방대” 부분은 사실이다(아래 §2 참조).


2. 모듈 규모와 서브패키지 구조

소스 파일 525개. 공급사 모듈 크기 순위:

Sabre        882 ████████████████████
Amadeus      873 ███████████████████▉
Galileo      525 ███████████▉              ← 본 모듈 (3위)
AmadeusNDC   357 ████████
Tway         253 █████▊
Koreanair    213 ████▊
Jinair       114 ██▌
Jejuair       99 ██▎
Singaporeair  88 ██
Lufthansa     87 ██
Groupair      34 ▊

규모의 대부분(525개 중 428개)은 infrastructure/soap의 Universal API 요청/응답 DTO다. “스키마 방대”의 정체가 바로 이것이다.

galileo/
├── application/            (8) 서비스 — 오퍼레이션별 비즈니스 로직
├── configuration/          (1) GalileoRedisConfiguration (FareItinerary 캐시 템플릿)
├── domain/
│   ├── model/              (1) GalileoFlightSearch (도메인 모델 + FareItinerary 등)
│   └── repository/         (1) GalileoFareItineraryRepository (Redis 해시 저장)
├── infrastructure/        (482) 외부 API 클라이언트 계층
│   ├── soap/              (428) Universal API DTO + GalileoClient  ← 모듈의 81%
│   │   ├── request/  (212)  16개 오퍼레이션별 RQ 패키지
│   │   └── response/ (215)
│   ├── rest/              ( 41) Travelport JSON 검색 + GalileoRestClient
│   │   ├── request/catalogproductofferings/
│   │   └── response/{authtoken, catalogproductofferings}/
│   ├── kps/              ( 10) KpsPaymentClient (BSP 카드/현금영수증) + 에러맵
│   └── krt/             (  3) KrtClient (운임규정 한글 번역)
├── interfaces/
│   └── controller/internals/ (6) Triple 내부 API 컨트롤러
└── support/              ( 26) 도메인 model/enums/util
    ├── enums/   CashReceiptType, CommissionType, ElementType, PassengerTypeCode, SsrType
    ├── model/   Booking, Fare, Leg, Passenger, Ticket, Queue*, Payment, Commission ...
    └── util/    AirportUtils, FormatUtils, PnrUtils

domain은 왜 이렇게 작은가

Galileo의 domain은 검색 결과 캐시 모델(FareItinerary)과 그 Redis 리포지토리뿐이다. 대부분의 “도메인스러운” 모델(Booking·Ticket·Passenger·Payment 등)은 support/model에 모여 있다. 이 모듈에서 비즈니스 의미가 담긴 모델을 찾을 때는 support/model을 먼저 보라.


3. 핵심 파일 표

경로(galileo/ 기준)역할비고
interfaces/controller/internals/GalileoSearchController.kt검색·검색상세 REST 진입점@CircuitBreaker(name="galileoSearch") + fallback 보유
interfaces/controller/internals/GalileoBookingController.kt예약 생성/조회/취소/repricing/divide/APIS 변경가장 엔드포인트 많음(11개)
interfaces/controller/internals/GalileoTicketingController.kt발권 준비(ready)/발권(issue)
interfaces/controller/internals/GalileoFareRuleController.kt운임규정/구조화 운임규정
interfaces/controller/internals/GalileoQueueController.ktGDS 큐 조회/제거
interfaces/controller/internals/GalileoCashReceiptController.kt현금영수증 발급/취소KPS 경유
application/GalileoFlightSearchService.kt검색 오케스트레이션 + Redis 캐시 + 코루틴 병렬 호출withBlocking/pmap
application/GalileoBookingService.kt (302L)예약·조회·repricing·divide·재가격검증모듈 최대 서비스
application/GalileoTicketingService.kt (265L)발권 ready/issue·커미션·비동기 취소
application/GalileoCancelService.kt (261L)취소·void·결제취소·반복(repeat)/비동기
application/GalileoCashReceiptService.kt현금영수증 발급/취소 + 실패 처리
application/GalileoFareRuleService.kt운임규정 조회(SOAP) + 한글 번역(KRT)
application/GalileoQueueService.kt멀티 PCC 큐 집계/제거(코루틴 병렬)online+offline PCC 순회
application/GalileoPassengerService.kt (31L)APIS(여권/탑승객 정보) 변경최소 서비스
infrastructure/soap/GalileoClient.kt (908L)Universal API SOAP 클라이언트 핵심pricing/book/ticketing/void/divide/retrieve/modify/queue 전부
infrastructure/rest/GalileoRestClient.kt (193L)Travelport JSON 검색 + 토큰 발급/캐시
infrastructure/kps/KpsPaymentClient.kt (196L)BSP 카드 승인/취소, 현금영수증 발급/취소한국형 결제 게이트웨이
infrastructure/krt/KrtClient.kt운임규정 영→한 번역
domain/repository/GalileoFareItineraryRepository.kt검색 결과 FareItinerary Redis 해시/단건 저장TTL=CacheSet.FARE_ITINERARY.ttl
configuration/RedisConfiguration.ktgalileoFareItineraryRedisTemplate 빈 + Gzip 직렬화클래스명은 GalileoRedisConfiguration
(공통) configuration/Properties.kt:421GalileoApiProperties(pcc/rest/soap/krt/kps + offline)galileo 모듈 밖, 공통 설정

4. 공개 인터페이스 (컨트롤러 + 엔드포인트 + 서비스)

모든 컨트롤러는 @RestController이며 베이스 경로는 /internals/GALILEO/.... 즉 외부 공개가 아니라 Triple 예약 시스템이 호출하는 내부 API다. 중앙 디스패처 없이 컨트롤러가 직접 노출되는 구조는 system-architecture·request-flow 참조.

4-1. 컨트롤러 → 엔드포인트

컨트롤러 (베이스 경로)메서드HTTP / 경로함수
GalileoSearchController /internals/GALILEO/search검색POST /search (CircuitBreaker galileoSearch)
검색상세GET /detail (amenity 결합)
GalileoBookingController /internals/GALILEO/bookings예약생성POST /create
APIS변경PUT /{pnr}changeApis
취소PUT /{pnr}/cancelcancel
예상취소GET /{pnr}/expected-cancelexpectedCancel
취소가능여부GET /{pnr}/cancelablecancelable
예약조회GET /{pnr}retrieve
PNR검증GET /{pnr}/check-pnrcheckPnr
확정GET /{pnr}/confirmconfirm
재가격GET /{pnr}/repricingrepricing
분리POST /{pnr}/dividedivide
GalileoTicketingController /internals/GALILEO/ticketing발권준비POST /readyready
발권POST /issue
GalileoFareRuleController /internals/GALILEO/fare-rules운임규정GET /getFareRules
구조화운임규정GET /structuredgetStructuredFareRules
GalileoQueueController /internals/GALILEO/queues큐조회GET /getQueues
큐제거PUT /remove
GalileoCashReceiptController /internals/GALILEO/cash-receipts발급POST /issueissueCashReceipt
취소PUT /cancelcancelCashReceipt

컨트롤러 → 서비스 의존 매핑(생성자 주입)

// GalileoBookingController.kt:23
class GalileoBookingController(
    private val bookingService: GalileoBookingService,
    private val galileoPassengerService: GalileoPassengerService,
    private val cancelService: GalileoCancelService,
)
// GalileoSearchController.kt:20 — flightSearchService + 공통 FlightAmenityService
// GalileoFareRuleController.kt:12 — fareRuleService + flightSearchService(키→FareItinerary 복원)

한 컨트롤러가 여러 서비스를 조합하고(예약 컨트롤러=예약+승객+취소), 반대로 한 서비스가 여러 컨트롤러에 쓰인다(GalileoFlightSearchService는 Search와 FareRule 양쪽). 이 호출 관계 전체는 caller-callee-map에 정리돼 있다.

4-2. application 서비스 목록(8개)

서비스담당 오퍼레이션
GalileoFlightSearchServiceSearch (+ FareRule 컨트롤러의 상세키 복원)
GalileoBookingServiceBooking(create/retrieve/confirm/repricing/divide/checkPnr)
GalileoPassengerServiceAPIS(승객 여권정보) 변경
GalileoCancelService취소/void/결제취소(동기·비동기·repeat)
GalileoTicketingServiceTicketing(ready/issue) + 커미션
GalileoFareRuleServiceFareRule 조회(SOAP) + 한글 번역(KRT)
GalileoQueueServiceQueue 집계/제거(멀티 PCC 코루틴 병렬)
GalileoCashReceiptServiceCashReceipt 발급/취소(KPS)

4-3. 지원 오퍼레이션 한눈에

flowchart LR
    Search["Search"] -->|"REST"| RestClient["GalileoRestClient"]
    RestClient --> TPJson["Travelport JSON v11"]
    Booking["Booking"] -->|"SOAP"| SoapClient["GalileoClient"]
    Ticketing["Ticketing"] -->|"SOAP"| SoapClient
    FareRule["FareRule"] -->|"SOAP"| SoapClient
    Queue["Queue"] -->|"SOAP"| SoapClient
    SoapClient --> UApi["Universal API<br/>AirService / UniversalRecordService"]
    SoapClient --> GdsQueue["GdsQueueService"]
    FareRuleKor["FareRule 번역"] --> KrtClient["KrtClient"]
    KrtClient --> KrtAspx["FareRuleTransKor.aspx"]
    Payment["CashReceipt / 결제"] --> KpsClient["KpsPaymentClient"]
    KpsClient --> KpsAspx["Kps 계열 .aspx"]

오퍼레이션별 상세 시퀀스·요청흐름은 galileo-operations에서 다룬다.


5. 중요도 별점

★★★ (최상)

근거

  1. 규모: 525파일로 3위. 11개 모듈 중 GDS 3대장(Sabre·Amadeus·Galileo)에 속한다.
  2. 오퍼레이션 풀세트: Search·Booking·Ticketing·FareRule·Queue·CashReceipt 6종을 모두 지원하는 몇 안 되는 모듈. 예약/발권/취소/재발권 흐름 학습에 사실상 표준 케이스.
  3. 하이브리드 프로토콜의 대표 사례: REST 검색 + SOAP 트랜잭션 + 별도 결제(KPS)/번역(KRT) 게이트웨이가 한 모듈에 공존한다. 어댑터 계층 설계를 가장 다층적으로 보여준다.
  4. 운영 복잡도: 멀티 PCC(online/offline)·채널/퍼널 매핑·Redis 토큰/검색 캐시·코루틴 병렬 검색/큐·Resilience4j 서킷브레이커가 모두 들어 있어, resilience-and-events·async-coroutines·configuration-and-infra 학습의 종합 실습장이다.

신입은 이 모듈을 “GDS 어댑터의 기준선”으로 삼고, 이후 Sabre/Amadeus의 추가 복잡도(stateful 세션 등)를 비교하며 확장 학습하는 것을 권장한다.

먼저 알아둘 함정 (요약)

  • GalileoProperties.getApiProperties()는 인자 없이 호출하면 MDCHolder의 판매채널/퍼널에 의존한다 → MDC가 비면 NOT_SUPPORTED_SALES_CHANNEL 로 깨진다.
  • SOAP 요청 직렬화 시 빈 네임스페이스/wstxns를 문자열 치환으로 제거한다(GalileoClient.kt:901~907) → 스키마 변경 시 깨지기 쉬운 지점.
  • 검색은 REST·예약은 SOAP라 토큰 캐시(REST)와 PCC 인증(SOAP)이 따로 논다. 인증 디버깅 시 두 경로를 구분해야 한다. 전체 지뢰 목록은 galileo-pitfalls 참조.

다음 노트