SAP 와 외부 시스템(MES · WEB · 그룹웨어 · 거래처 시스템) 간 데이터를 주고받는 채널은 여러 갈래가 있습니다. 그중 PI/PO(Process Integration/Orchestration) 또는 SAP Integration Suite 기반의 ABAP Proxy 는 표준 인터페이스 정의(WSDL/XSD)를 SAP 시스템에 그대로 가져와 ABAP 클래스로 생성해 쓰는 가장 정식 경로입니다.
ABAP Proxy 의 가장 큰 특징은 방향에 따라 두 종류 로 나뉜다는 점입니다. Outbound(송신) Proxy 는 SAP 가 데이터를 외부로 내보낼 때 사용하는 Consumer Proxy 이고, Inbound(수신) Proxy 는 외부에서 들어온 데이터를 SAP 가 받아서 처리하는 Provider Proxy 입니다. SPROXY 에서 같은 화면으로 둘 다 보이기 때문에 처음에는 어느 쪽이 어느 쪽인지 헷갈리기 쉽습니다.
이 글에서는 SAP 가 시작점(Outbound) 인 경우에 한정해서 SPROXY 에서 인터페이스를 확인하고, 자동 생성된 Proxy Class 에 들어가 메서드를 찾고, 실제 Source 를 어떻게 구현하는지 4단계로 정리합니다. 검증 포인트(ABAP Object = CLAS Class)와 Dynamic Call 패턴(if_proxy_client~execute)도 함께 다룹니다.
핵심 — Outbound Proxy vs Inbound Proxy vs RFC
| 구분 | Outbound Proxy (송신) | Inbound Proxy (수신) | RFC FM |
|---|---|---|---|
| 방향 | SAP → 외부 | 외부 → SAP | 양방향 |
| ABAP Object | CLAS Class (Consumer Proxy) |
INTF Interface (Provider) |
Function Module |
| 구현 위치 | 자동 생성된 Class 의 메서드 Source | 인터페이스 구현 Class 의 메서드 | SE37 FM 본문 |
| 호출 방식 | ABAP 에서 Proxy Class 인스턴스화 후 호출 | 미들웨어(PI/PO)가 SAP 로 push | CALL FUNCTION ... DESTINATION |
| 프로토콜 | SOAP / HTTP / XI (WSDL 기반) | SOAP / HTTP / XI | SAP RFC 프로토콜 |
| 모니터링 | SXMB_MONI · SXI_MONITOR |
SXMB_MONI · SRT_MONI |
SM58 |
송수신 방향 판별 핵심 — SPROXY 에서 인터페이스를 열었을 때 ABAP Object 필드가 CLAS Class 면 SAP 가 시작점인 Outbound Proxy, INTF Interface 면 외부가 시작점인 Inbound Proxy 입니다. 이 규칙 하나로 어느 방향인지 즉시 알 수 있습니다.
1단계 — SPROXY 에서 인터페이스 확인
PI/PO 또는 Integration Suite 에 정의된 Service Interface 가 SAP 로 import 되면 SPROXY 트랜잭션에서 자동으로 트리에 나타납니다. 해당 인터페이스를 더블클릭해서 들어간 뒤 ABAP Object 필드 를 확인합니다.
[1] SE38 화면에서 SPROXY 실행
└ T-Code: SPROXY
[2] 좌측 트리에서 Namespace → Service Interface 선택
└ 예: http://www.example.com/XX_OUT_Result
└ Service Interface: ZXX_OUT_MI_C
[3] Properties 탭에서 ABAP Object 확인
☑ CLAS Class → SAP 가 시작점 (Outbound · 이 글의 대상)
☐ INTF Interface → 외부가 시작점 (Inbound · 다음 글)
Service Consumer 화면의 핵심 필드
SPROXY 에서 Outbound Proxy 를 열면 다음과 같은 필드 구성이 보입니다. 회사 실제 값이 아니라 일반화된 예시 값으로 정리하면:
| 필드 | 예시값 | 의미 |
|---|---|---|
| Name | ZXX_OUT_MI_C |
PI/PO 에 정의된 Service Interface 이름. 접미 _C = Consumer |
| Namespace | http://www.example.com/XX_OUT_Result |
PI/PO 의 Software Component Namespace |
| ABAP Object | CLAS Class |
SAP 가 시작점 임을 알려주는 핵심 표시 |
| ABAP Name | ZXICO_XX_OUT_MI_C |
자동 생성된 Proxy Class 의 ABAP 이름. CO prefix 가 Consumer 의미 |
| Prefix | ZXI |
생성 시 지정한 클래스명 Prefix |
| Source | Enterprise Services Repository |
ESR 에서 가져온 인터페이스 |
| Description | Proxy Class (generated) |
자동 생성됨을 표시 — 직접 수정 시 주의 |
| Package | ZXX_ID |
Proxy 클래스 저장 패키지 |
핵심은 ABAP Object = CLAS Class 행입니다. 이 한 줄로 송신/수신을 즉시 구분합니다.
2단계 — Proxy Class 들어가기 (ABAP Name 더블클릭)
SPROXY 화면에서 인터페이스 확인이 끝났으면 ABAP Name 필드의 값(예: ZXICO_XX_OUT_MI_C) 을 더블클릭 합니다. 그러면 자동 생성된 Proxy Class 가 SE24(또는 SE80) 화면으로 열립니다.
[1] SPROXY · Properties 탭에서 ABAP Name 클릭
└ ZXICO_XX_OUT_MI_C
[2] 더블클릭하면 자동으로 SE24 클래스 빌더로 이동
└ Class/Interface: ZXICO_XX_OUT_MI_C
[3] 상단 탭에서 "방법(Methods)" 탭 선택
└ 등록정보 · 인터페이스 · Friends · 속성 · 방법 · 이벤트 · 내부유형 · 별칭
3단계 — Method 찾기
방법(Methods) 탭에 들어가면 Proxy 가 자동으로 만든 메서드들이 보입니다. SAP Proxy Runtime Framework 가 내려준 표준 메서드와, 이 인터페이스에만 해당하는 비즈니스 메서드 가 함께 있습니다.
Proxy Class 의 메서드 구성
| 메서드 | 레벨 | 설명 |
|---|---|---|
IF_PROXY_BASIS_INTERNAL~CREATE_FRAME |
Static | 프록시 프레임 생성 (런타임 내부용 — 손대지 않음) |
IF_PROXY_BASIS~GET_PROTOCOL |
Instance | 프로토콜(SOAP / HTTP / XI) 핸들 획득. 헤더 추가 시 사용 |
IF_PROXY_BASIS~GET_TRANSPORT_BINDIN |
Instance | Transport Binding 정보 획득 (Destination · URL 등) |
IF_PROXY_CLIENT~EXECUTE |
Instance | 실제 송신 실행 메서드 (Dynamic Call 진입점) |
CONSTRUCTOR |
Instance | 프록시 인스턴스 생성자 |
XX_OUT_MI_C ★ |
Instance | 비즈니스 메서드 — Service Interface 이름과 동일. 여기에 Source 를 구현 |
핵심은 마지막 줄의 XX_OUT_MI_C 처럼 Service Interface 이름과 같은 메서드 입니다. 이 메서드를 더블클릭 해서 들어간 뒤 Source 를 구현합니다.
4단계 — Method Source 구현 (Dynamic Call 패턴)
비즈니스 메서드 Source 안에서는 직접 외부에 SOAP 호출을 던지는 게 아니라, IF_PROXY_CLIENT~EXECUTE 를 Dynamic Call 형태로 호출 합니다. 메서드 이름과 파라미터를 런타임에 묶어 던지는 패턴입니다.
method XX_OUT_MI_C.
data:
ls_parmbind type abap_parmbind,
lt_parmbind type abap_parmbind_tab.
" 1) Parameter binding 구성 — OUTPUT 파라미터를 IMPORTING 으로 묶음
ls_parmbind-name = 'OUTPUT'.
ls_parmbind-kind = cl_abap_objectdescr=>importing.
get reference of OUTPUT into ls_parmbind-value.
insert ls_parmbind into table lt_parmbind.
" 2) Proxy Runtime 에 송신 위임
if_proxy_client~execute(
exporting
method_name = 'XX_OUT_MI_C'
changing
parmbind_tab = lt_parmbind
).
endmethod.
코드의 핵심 포인트 3가지:
abap_parmbind구조체는 동적 메서드 호출의 파라미터 바인딩 단위.name·kind·value세 필드 구성.kind는 파라미터 종류 —cl_abap_objectdescr=>importing·exporting·changing·receiving중 하나.get reference of OUTPUT into ls_parmbind-value— 메서드 시그니처의 OUTPUT 파라미터(보통 PI 에서 정의한 송신 데이터 구조) 의 참조를 바인딩에 넣음.
호출자(예: MM 모듈의 Z 리포트) 입장에서는 이 비즈니스 메서드만 호출하면 됩니다. 내부에서 어떻게 송신되는지는 SAP Proxy Runtime Framework 가 알아서 처리.
" ─────────────── 호출 쪽 (Z 리포트) ───────────────
DATA: lo_proxy TYPE REF TO zxico_xx_out_mi_c,
ls_output TYPE zxx_out_mt.
" 1) 송신 데이터 채우기
ls_output-header-bukrs = '1000'.
ls_output-header-werks = '0001'.
" ... (PI 에서 정의한 메시지 타입의 필드들)
" 2) Proxy 인스턴스 생성 후 호출
TRY.
CREATE OBJECT lo_proxy.
lo_proxy->xx_out_mi_c(
EXPORTING
output = ls_output " 비즈니스 데이터
).
COMMIT WORK. " 비동기일 때 필수
CATCH cx_ai_system_fault INTO DATA(lx_sys).
WRITE: / 'System Fault:', lx_sys->get_text( ).
CATCH cx_ai_application_fault INTO DATA(lx_app).
WRITE: / 'Application Fault:', lx_app->get_text( ).
ENDTRY.
동기 vs 비동기 호출 차이
SPROXY 에서 생성된 Service Interface 가 동기(Synchronous) 인지 비동기(Asynchronous) 인지에 따라 호출 패턴이 살짝 달라집니다.
| 구분 | Synchronous (동기) | Asynchronous (비동기) |
|---|---|---|
| 응답 대기 | 외부 응답 받을 때까지 대기 | 메시지 큐에 넣고 즉시 리턴 |
| 응답 파라미터 | OUTPUT · INPUT 모두 존재 | OUTPUT 만 존재 |
| COMMIT WORK | 불필요 (호출 시점에 즉시 송신) | 필수 — COMMIT WORK 호출 후 큐로 전달 |
| 모니터링 | SRT_MONI |
SXMB_MONI · SXI_MONITOR |
| 사용 시점 | 즉시 결과 필요 (조회 응답 · Validation) | 결과 통보 (전표 송신 · 마스터 변경 알림) |
비동기에서 COMMIT WORK 를 빠뜨리면 메시지가 큐에 안 들어가서 외부 시스템이 영원히 데이터를 못 받습니다. 가장 흔한 실수 중 하나.
자주 빠뜨리는 함정
COMMIT WORK 누락 (비동기)
비동기 Proxy 호출 후 COMMIT WORK 를 호출하지 않으면 메시지가 SAP 큐에 등록되지 않습니다. 호출은 성공한 것처럼 보이지만 SXMB_MONI 에 메시지가 안 보입니다.
예외 처리 누락
CX_AI_SYSTEM_FAULT 와 CX_AI_APPLICATION_FAULT 두 예외를 반드시 TRY-CATCH 로 잡아야 합니다. 안 잡으면 네트워크 끊김 한 번에 호출 프로그램이 덤프.
Proxy Class 의 자동 생성 코드 직접 수정
비즈니스 메서드 Source 외에 자동 생성된 표준 메서드(CONSTRUCTOR · IF_PROXY_BASIS~*) 를 손대면 다음번 Proxy regeneration 때 덮어쓰이거나 활성화 실패가 일어납니다. 비즈니스 메서드(인터페이스 이름과 같은 메서드) 만 수정.
Namespace 변경 후 Proxy regenerate 안 함
PI/PO 쪽에서 Service Interface 의 Namespace 나 Operation 이름을 바꿨는데 SAP 쪽 Proxy 를 다시 생성하지 않으면, 호출은 가는데 PI 가 받지 못합니다. 인터페이스 변경 시 항상 SPROXY 에서 regenerate 필요.
Release Status 가 Not Released
개발 단계에서는 Not Released 로 두지만, 운영 전송 전에 Release 해줘야 합니다. Release 안 된 Proxy 는 운영기에 트랜스포트되어도 활성화되지 않습니다.
전체 코드 — 복사용 통합본
위 패턴을 한 화면에 정리한 호출자 측 코드입니다. PI/PO 에 정의된 송신 인터페이스가 비동기 단방향(Asynchronous Outbound) 라고 가정.
REPORT zrxx_proxy_send_demo.
DATA: lo_proxy TYPE REF TO zxico_xx_out_mi_c,
ls_output TYPE zxx_out_mt. " PI 메시지 타입
* ─────────────────────────────────────────────
* 1) 송신 데이터 채우기 (마스터/트랜잭션 데이터 → 메시지 타입 매핑)
* ─────────────────────────────────────────────
ls_output-header-bukrs = '1000'.
ls_output-header-werks = '0001'.
ls_output-header-belnr = '4500000001'.
ls_output-header-bldat = sy-datum.
ls_output-item-matnr = 'TEST-MAT-001'.
ls_output-item-menge = '100'.
ls_output-item-meins = 'EA'.
* ─────────────────────────────────────────────
* 2) Proxy 인스턴스 생성 후 비즈니스 메서드 호출
* ※ 비즈니스 메서드 이름 = Service Interface 이름
* ─────────────────────────────────────────────
TRY.
CREATE OBJECT lo_proxy.
lo_proxy->xx_out_mi_c(
EXPORTING
output = ls_output
).
* ─────────────────────────────────────────────
* 3) 비동기는 반드시 COMMIT WORK
* 동기였다면 이 줄 불필요
* ─────────────────────────────────────────────
COMMIT WORK.
WRITE: / '송신 완료 — SXMB_MONI 에서 확인'.
* ─────────────────────────────────────────────
* 4) 시스템 / 애플리케이션 예외 처리
* ─────────────────────────────────────────────
CATCH cx_ai_system_fault INTO DATA(lx_sys).
WRITE: / '시스템 오류:', lx_sys->get_text( ).
CATCH cx_ai_application_fault INTO DATA(lx_app).
WRITE: / '비즈니스 오류:', lx_app->get_text( ).
ENDTRY.
자동 생성된 Proxy Class 의 비즈니스 메서드 Source(4단계에서 다룬 부분) 까지 합쳐 보면 전체 송신 흐름이 다음 두 ABAP 코드 조각으로 완성됩니다.
" ─────────────── Proxy Class 비즈니스 메서드 (자동 생성 후 직접 작성) ───────────────
method XX_OUT_MI_C.
data:
ls_parmbind type abap_parmbind,
lt_parmbind type abap_parmbind_tab.
ls_parmbind-name = 'OUTPUT'.
ls_parmbind-kind = cl_abap_objectdescr=>importing.
get reference of OUTPUT into ls_parmbind-value.
insert ls_parmbind into table lt_parmbind.
if_proxy_client~execute(
exporting
method_name = 'XX_OUT_MI_C'
changing
parmbind_tab = lt_parmbind
).
endmethod.
요약
| 단계 | 위치 | 핵심 행동 |
|---|---|---|
| 1 | SPROXY |
인터페이스 더블클릭 → ABAP Object = CLAS Class 확인 (송신) |
| 2 | SPROXY · Properties | ABAP Name 더블클릭 → SE24 클래스 빌더로 이동 |
| 3 | SE24 · 방법 탭 |
Service Interface 이름과 같은 비즈니스 메서드 더블클릭 |
| 4 | 메서드 Source | abap_parmbind 구성 → if_proxy_client~execute 호출 |
| 5 | 호출자 리포트 | Proxy 인스턴스 생성 → 비즈니스 메서드 호출 → 비동기면 COMMIT WORK |
SAP Outbound Proxy 의 본질은 PI/PO 가 정의한 메시지 구조를 SAP 가 ABAP 클래스 형태로 받아서, 비즈니스 메서드 한 줄 호출만으로 외부로 송신 하는 패턴입니다. 어디서부터 SAP 가 모르고 자동 처리해주는지 — Service Interface 정의(PI) · 자동 생성된 표준 메서드(Proxy Runtime) · COMMIT WORK 시점의 큐 적재(SAP Kernel) — 의 경계만 잡으면 송신 로직 자체는 항상 위 4단계 패턴이 반복됩니다.
곧 정리할 후속 글은 정확히 같은 SPROXY 화면에서 ABAP Object 가 INTF Interface 인 케이스, 즉 외부 → SAP Inbound Proxy 의 구현 방법입니다.
Disclaimer — 이 포스트는 실무 정리 노트를 바탕으로 AI 보조로 정리되었습니다.
ABAP Proxy 의 세부 동작과 트랜잭션(SPROXY · SXMB_MONI · SRT_MONI 등)은 NetWeaver 버전(ECC 6.0 / S/4HANA on-premise · Cloud)과 PI/PO · Integration Suite 연동 구성에 따라 일부 화면 구성이 다를 수 있으니, 실제 적용 시에는 해당 시스템의 미들웨어 구성을 함께 확인하시기 바랍니다.