이전 글(“[SAP ABAP] Outbound Proxy 구현 — SAP에서 외부로 데이터 송신”) 에서는 SAP 가 시작점 인 송신 시나리오를 다뤘습니다. 이번 글은 반대 방향 — 외부 시스템(MES · WEB · 거래처) 이 시작점이 되어 SAP 로 데이터를 밀어 넣는 Inbound Proxy 구현입니다.
방향이 반대이기 때문에 SPROXY 에서 보이는 검증 포인트도 정반대입니다. Outbound 가 ABAP Object = CLAS Class 였다면, Inbound 는 ABAP Object = INTF Interface. 자동 생성되는 산출물도 클래스 1개가 아니라 인터페이스(Provider Interface) + 구현 클래스(Implementing Class) 한 쌍입니다.
이 글에서는 SPROXY 에서 인터페이스 식별 → Implementing Class 진입 → 인터페이스 메서드 더블클릭 → 실제 Source 구현(외부 메시지 → 내부 CBO 구조체 매핑 → 비즈니스 FM 호출) 까지 4단계로 정리합니다.
핵심 — Outbound Proxy vs Inbound Proxy
| 구분 | Outbound Proxy (송신) | Inbound Proxy (수신 · 이 글의 대상) |
|---|---|---|
| 방향 | SAP → 외부 | 외부 → SAP |
| ABAP Object | CLAS Class (Consumer) |
INTF Interface (Provider) |
| 자동 생성 산출물 | Proxy Class 1개 | Provider Interface + Implementing Class 한 쌍 |
| 구현 위치 | 생성된 Class 의 비즈니스 메서드 | Implementing Class 의 ~메서드명 Source |
| 호출 주체 | SAP 의 Z 리포트 / FM | PI / PO / Integration Suite (외부 메시지 도착 시 자동 트리거) |
| 모니터링 | SXMB_MONI · SRT_MONI |
SXMB_MONI · SXI_MONITOR |
| 디버깅 | Z 리포트에 breakpoint | SPROXY 내부 디버깅(External Breakpoint) 또는 SXMB_MONI 메시지 재처리 |
송수신 판별 핵심은 동일 — SPROXY Properties 탭의 ABAP Object 한 줄. INTF Interface 면 외부가 시작점, 즉 SAP 가 받는 쪽인 Inbound Proxy 입니다.
1단계 — SPROXY 에서 인터페이스 확인
[1] T-Code SPROXY 실행
[2] 좌측 트리에서 Namespace → Service Provider 선택
└ 예: http://www.example.com/XX_IN_Info
└ Service Interface: ZXX_IN_MI
[3] Properties 탭에서 ABAP Object 확인
☐ CLAS Class → SAP 가 시작점 (Outbound · 이전 글)
☑ INTF Interface → 외부가 시작점 (Inbound · 이 글)
Service Provider 화면의 핵심 필드
Inbound Proxy 의 Properties 탭은 Outbound 와 비슷하지만 Implementing Class 와 WebService Definition 두 행이 추가됩니다. Outbound 에는 없던 항목이고, 구현이 들어가는 위치를 알려주는 가장 중요한 단서입니다.
| 필드 | 예시값 | 의미 |
|---|---|---|
| Name | ZXX_IN_MI |
PI/PO 에 정의된 Service Interface 이름. _IA_MI = Inbound Asynchronous Message Interface 패턴 |
| Namespace | http://www.example.com/XX_IN_Info |
PI/PO 의 Software Component Namespace |
| ABAP Object | INTF Interface |
외부가 시작점 임을 알려주는 핵심 표시 |
| ABAP Name | ZXIII_XX_IN_MI |
자동 생성된 Provider Interface 이름. III = Inbound Interface Implementation 의 의미 |
| Description | Proxy Interface (generated) |
Outbound 에서는 Proxy Class (generated) 였던 자리 |
| Implementing Class ★ | ZXICL_XX_IN_MI |
실제 Source 가 들어가는 클래스. 이 행을 더블클릭하는 게 다음 단계의 시작점 |
| WebService Definition | ZXX_IN_MI |
SOAMANAGER 에서 endpoint 바인딩에 사용되는 WSDL |
| Package | ZXX_ID |
Proxy 인터페이스/클래스 저장 패키지 |
핵심은 Implementing Class 행입니다. Outbound 와 가장 다른 점이고, 이 클래스에 실제 비즈니스 로직이 들어갑니다.
2단계 — Implementing Class 들어가기
SPROXY Properties 탭에서 Implementing Class 필드값(예: ZXICL_XX_IN_MI) 을 더블클릭 합니다. 그러면 SE24 Class Builder 화면이 열립니다.
[1] SPROXY · Properties 탭에서 Implementing Class 클릭
└ ZXICL_XX_IN_MI
[2] 더블클릭 → SE24 클래스 빌더로 이동
└ Class/Interface: ZXICL_XX_IN_MI
└ 이 클래스는 ZXIII_XX_IN_MI 인터페이스를 구현 (implements)
[3] 상단 탭에서 "방법(Methods)" 탭 선택
Outbound 와의 차이 — Outbound 는 자동 생성된 Class 1개 안에 표준 메서드들과 비즈니스 메서드가 같이 있었지만, Inbound 는 인터페이스 + 구현 클래스 한 쌍 구조. 인터페이스는 contract(메서드 선언)만 있고, 실제 코드는 구현 클래스에 들어갑니다.
3단계 — Method 찾기
방법(Methods) 탭에 들어가면 Outbound 때처럼 표준 메서드들이 잔뜩 보이지 않습니다. 인터페이스에서 상속받은 메서드 한 개 만 있는 게 보통입니다.
| 메서드 | 레벨 | 가시성 | 설명 |
|---|---|---|---|
ZXIII_XX_IN_MI~XX_IN_MI ★ |
Instance | Public | 외부 메시지가 도착하면 자동 호출되는 진입점. 여기에 Source 를 구현 |
메서드 이름은 {인터페이스명}~{메서드명} 형태. 비동기면 시그니처에 INPUT 파라미터 하나만, 동기면 INPUT + OUTPUT 두 개가 자동 생성됩니다. 이 메서드를 더블클릭 해서 Source 로 들어갑니다.
4단계 — Method Source 구현
Inbound Proxy 메서드 안에서 일반적으로 하는 일은 세 가지입니다:
[1] INPUT 파라미터에서 메시지 구조 추출
└ PI/PO 가 외부 XML 을 자동으로 구조체로 변환해서 INPUT 에 넣어줌
└ INPUT-{Message Type}-{Field Group} 경로로 접근
[2] 외부 메시지 구조 → SAP 내부 CBO 구조체로 매핑
└ LOOP 돌면서 MOVE-CORRESPONDING 또는 필드별 매핑
[3] 비즈니스 로직 처리 (보통 Z FM 호출)
└ CBO 테이블 INSERT/UPDATE · 표준 BAPI 호출 · 후속 처리
자동 생성된 코드 골격(스켈레톤)과 실제 구현부를 함께 보면 다음과 같습니다.
method ZXIII_XX_IN_MI~XX_IN_MI.
* **** **** INSERT IMPLEMENTATION HERE **** ****
* (자동 생성된 주석 — 실제 구현은 이 아래에 작성)
" 1) 메시지 구조 / 내부 작업 구조 선언
DATA: ls_input TYPE zxixx_in_dt_zsxx0575, " 외부 메시지 데이터 타입
lt_input TYPE zxixx_in_dt_zsxx_tab. " 테이블 타입
DATA: is_data1 TYPE zsxx0575, " 내부 CBO 구조체
it_data1 TYPE TABLE OF zsxx0575. " 내부 CBO 테이블
CLEAR : ls_input, is_data1.
REFRESH: lt_input, it_data1.
" 2) INPUT 파라미터에서 메시지 데이터 추출
" 경로 = INPUT-{Message Type 명}-{Field Group 명}
lt_input[] = input-xx_in_mt-zsxx0575[].
" 3) 외부 메시지 → 내부 CBO 구조체 매핑
LOOP AT lt_input INTO ls_input.
CLEAR is_data1.
MOVE-CORRESPONDING ls_input TO is_data1.
APPEND is_data1 TO it_data1.
ENDLOOP.
" 4) 비즈니스 로직 처리 — Z FM 으로 위임
CALL FUNCTION 'Z_XX_PROCESS_INBOUND'
TABLES
it_data1 = it_data1.
endmethod.
코드의 핵심 포인트 4가지:
INPUT파라미터는 메서드 시그니처에 이미 자동으로 선언 돼 있음.DATA로 다시 선언할 필요 없음.INPUT-{MT}-{FG}경로 — PI/PO 의 Data Type 구조가 그대로 ABAP 중첩 구조로 매핑됨. SPROXY 의 Objects 탭에서 Data Type 구조를 펼쳐 보면 경로 확인 가능.- 메시지 구조와 내부 CBO 구조가 다르기 때문에 중간 매핑 단계(MOVE-CORRESPONDING) 가 거의 필수. 필드명이 다르면 필드별 명시 매핑.
- 비즈니스 로직은 별도 FM 또는 Class 메서드로 위임. Inbound Proxy 메서드는 “라우터” 역할만 하고, 실제 처리는 재사용 가능한 단위로 분리.
비동기 Inbound 인 경우 메서드가 끝나면 SAP 가 자동으로 메시지를 처리 완료 상태로 표시합니다. 동기 Inbound 라면 메서드 안에서 OUTPUT 파라미터에 응답을 채워야 외부 시스템이 결과를 받습니다.
동기 vs 비동기 응답 처리
| 구분 | 비동기 Inbound | 동기 Inbound |
|---|---|---|
| 메서드 파라미터 | INPUT 만 |
INPUT + OUTPUT |
| 응답 | 없음. 처리 결과는 SXMB_MONI 로 통보 | OUTPUT 채워서 즉시 반환 |
| 예외 처리 | RAISE EXCEPTION TYPE cx_ai_application_fault |
동일 + 외부 시스템에 응답으로 전달됨 |
| 모니터링 | SXMB_MONI · 실패 시 재처리 가능 |
SRT_MONI · 응답 즉시 처리 종료 |
| 주 사용 | 대량 트랜잭션 수신 (입고 알림 · 마스터 동기화) | 즉시 검증/조회 요청 (재고 확인 · 가용성 체크) |
비동기 Inbound 에서 예외를 그냥 던지면 SAP 가 메시지를 “실패” 상태로 표시하고 SXMB_MONI 에서 재처리 가능하게 큐에 보관합니다. cx_ai_application_fault 를 명시적으로 raise 하면 외부에 비즈니스 오류로 전달, cx_ai_system_fault 는 기술적 오류로 전달됩니다.
자주 빠뜨리는 함정
COMMIT WORK 직접 호출
Outbound 에서 비동기에 필수였던 COMMIT WORK 를 Inbound 메서드 안에서 호출하면 안 됩니다. Proxy Framework 이 메서드 종료 시점에 자동 처리. 직접 호출하면 트랜잭션 LUW 가 꼬여서 메시지가 두 번 커밋되거나 롤백이 깨집니다.
예외를 그냥 잡아서 무시
TRY.
CALL FUNCTION 'Z_XX_PROCESS_INBOUND' ...
CATCH cx_root.
" 아무것도 안 함 ← ❌ 절대 안 됨
ENDTRY.
비즈니스 처리 실패를 이렇게 묻어버리면 SXMB_MONI 에서는 “성공” 으로 보이는데 SAP DB 에는 데이터가 안 들어간 유령 상태가 됩니다. 실패는 반드시 cx_ai_application_fault 로 다시 던져 외부에도 알려야 합니다.
Implementing Class 자동 생성 후 활성화 누락
SPROXY 에서 Provider 인터페이스를 처음 생성하면 Implementing Class 가 자동 생성되지만 비활성 상태. 메서드 Source 작성 후 반드시 클래스 활성화(Ctrl+F3) 필요. 비활성 상태에서는 외부 메시지가 들어와도 SAP 가 처리를 못 합니다.
Data Type 경로 잘못 입력
input-xx_in_mt-zsxx0575[] 같은 중첩 경로는 PI/PO 에서 정의한 Data Type 구조를 그대로 따라야 합니다. 한 단계라도 틀리면 컴파일은 되는데 런타임에 INPUT 이 비어 보이는 함정. SPROXY 의 Objects 탭에서 Data Type 트리를 펼쳐 정확한 경로 확인 후 코딩.
인터페이스 변경 시 클래스 regenerate 안 함
PI/PO 쪽에서 Service Interface 의 메시지 구조를 바꿨는데 SPROXY 에서 regenerate 를 누르지 않으면 Implementing Class 의 INPUT 타입이 옛날 구조를 그대로 쓰게 됩니다. 인터페이스 변경 시 SPROXY 우클릭 > Regenerate 필수.
전체 코드 — 복사용 통합본
Implementing Class 의 메서드 Source 하나로 외부 → SAP 수신 흐름이 완결됩니다. 자동 생성된 스켈레톤에서 실제 비즈니스 로직만 채워 넣은 형태:
method ZXIII_XX_IN_MI~XX_IN_MI.
* ─────────────────────────────────────────────
* 1) 작업 구조 선언
* INPUT 은 메서드 시그니처에 이미 있으므로 추가 선언 X
* ─────────────────────────────────────────────
DATA: ls_input TYPE zxixx_in_dt_zsxx0575, " 외부 메시지 ROW 타입
lt_input TYPE zxixx_in_dt_zsxx_tab. " 외부 메시지 테이블 타입
DATA: is_data1 TYPE zsxx0575, " 내부 CBO ROW
it_data1 TYPE TABLE OF zsxx0575. " 내부 CBO 테이블
CLEAR : ls_input, is_data1.
REFRESH: lt_input, it_data1.
* ─────────────────────────────────────────────
* 2) INPUT 에서 메시지 데이터 추출
* 경로 = INPUT-{Message Type}-{Field Group}
* ※ SPROXY · Objects 탭에서 Data Type 경로 확인
* ─────────────────────────────────────────────
lt_input[] = input-xx_in_mt-zsxx0575[].
* ─────────────────────────────────────────────
* 3) 외부 메시지 → 내부 CBO 매핑
* ─────────────────────────────────────────────
LOOP AT lt_input INTO ls_input.
CLEAR is_data1.
MOVE-CORRESPONDING ls_input TO is_data1.
APPEND is_data1 TO it_data1.
ENDLOOP.
* ─────────────────────────────────────────────
* 4) 비즈니스 로직 위임 — Z FM 호출
* 실패는 cx_ai_application_fault 로 raise
* ─────────────────────────────────────────────
TRY.
CALL FUNCTION 'Z_XX_PROCESS_INBOUND'
TABLES
it_data1 = it_data1.
CATCH cx_root INTO DATA(lx_err).
RAISE EXCEPTION TYPE cx_ai_application_fault
EXPORTING
textid = cx_ai_application_fault=>standard_error.
ENDTRY.
* ─────────────────────────────────────────────
* ※ COMMIT WORK 직접 호출 금지 — Framework 가 처리
* ─────────────────────────────────────────────
endmethod.
요약
| 단계 | 위치 | 핵심 행동 |
|---|---|---|
| 1 | SPROXY |
인터페이스 더블클릭 → ABAP Object = INTF Interface 확인 (수신) |
| 2 | SPROXY · Properties | Implementing Class 더블클릭 → SE24 클래스 빌더로 이동 |
| 3 | SE24 · 방법 탭 |
{인터페이스}~{메서드} 더블클릭 |
| 4 | 메서드 Source | INPUT 추출 → 내부 CBO 매핑 → 비즈니스 FM 호출 → 예외는 cx_ai_application_fault 로 raise |
| 5 | 클래스 활성화 | Ctrl+F3 으로 Implementing Class 활성화 → 외부 메시지 수신 준비 완료 |
Inbound Proxy 의 본질은 PI/PO 가 외부 XML 을 자동으로 ABAP 구조체로 변환해 INPUT 에 넣어주면, SAP 는 그걸 내부 CBO/표준 객체로 매핑해 비즈니스 로직에 던지기만 하면 된다는 점입니다. 외부 통신 자체는 Framework 가 모두 가려주고, 개발자는 “구조 변환 + 비즈니스 로직 위임” 두 가지에만 집중하면 됩니다.
이전 글 — “[SAP ABAP] Outbound Proxy 구현 — SAP에서 외부로 데이터 송신” 과 함께 보면 SPROXY 한 화면 안에서 송신/수신 두 방향이 모두 정리됩니다.
Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다.
ABAP Proxy 의 세부 동작과 트랜잭션(SPROXY · SXMB_MONI · SXI_MONITOR · SOAMANAGER 등)은 NetWeaver 버전(ECC 6.0 / S/4HANA on-premise · Cloud)과 PI/PO · Integration Suite 연동 구성에 따라 일부 화면 구성이 다를 수 있으니, 실제 적용 시에는 해당 시스템의 미들웨어 구성을 함께 확인하시기 바랍니다.