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"
모든 호출에 타깃 브랜치(targetBranch = branchCode) 와 PCC(Pseudo City Code) 가 붙는다. PCC는 GDS에서 여행사 단말을 식별하는 가상 도시 코드로, GDS 연동의 전형적 특징이다.
Properties.kt:421GalileoApiProperties.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) 를 모두 제공한다. 이 모듈은 둘을 오퍼레이션별로 골라 쓴다.
신형 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 참조).
Galileo의 domain은 검색 결과 캐시 모델(FareItinerary)과 그 Redis 리포지토리뿐이다. 대부분의 “도메인스러운” 모델(Booking·Ticket·Passenger·Payment 등)은 support/model에 모여 있다. 이 모듈에서 비즈니스 의미가 담긴 모델을 찾을 때는 support/model을 먼저 보라.
모든 컨트롤러는 @RestController이며 베이스 경로는 /internals/GALILEO/.... 즉 외부 공개가 아니라 Triple 예약 시스템이 호출하는 내부 API다. 중앙 디스패처 없이 컨트롤러가 직접 노출되는 구조는 system-architecture·request-flow 참조.
// GalileoBookingController.kt:23class 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에 정리돼 있다.