본문으로 건너뛰기
← 블로그로 돌아가기

이 글의 모듈: Integration Flow Helper

SAP CPI의 알 수 없는 header와 속성: 조용히 실패하기 전에 찾아내기

SAP CPI에서 철자가 틀리거나 없는 header 또는 exchange property가 오류 없이 실패하는 이유, 흔한 원인, 설계 시점과 런타임에 이를 찾아내는 방법을 설명합니다.

SAP CPI의 알 수 없는 header와 속성: 조용히 실패하기 전에 찾아내기

한 번도 설정되지 않은 header가 있어도 SAP CPI iFlow는 멈추지 않습니다. 그 header를 읽는 표현식은 빈 값을 반환하고, Router 조건은 false가 되며, 페이로드 필드는 비어 있는 채로 메시지는 계속 진행됩니다. 오류가 나더라도 몇 단계 뒤나 수신 시스템에서 나타납니다.

이 글에서는 없는 header와 exchange property가 조용히 실패하는 이유, 반복해서 나타나는 원인, 그리고 메시지보다 먼저 이를 잡아내는 점검 방법을 설명합니다.

없는 이름이 오류를 일으키지 않는 이유

Apache Camel은 존재하지 않는 header나 속성을 오류가 아니라 빈 값으로 취급합니다. 선택적인 값에는 편리하지만, 바로 그 때문에 오타가 몇 달 동안 iFlow에 남아 있을 수 있습니다. 어떻게 보이는지는 그 이름을 읽는 위치에 따라 다릅니다.

  • ${property.orderId} 같은 Content Modifier 값은 빈 문자열이 됩니다.
  • ${header.orderType} = 'EXPRESS' 같은 Router 또는 Filter 조건은 false로 평가되어, 메시지가 다른 경로, 흔히 기본 경로로 갑니다.
  • /orders/${property.orderId} 같은 수신기 주소는 /orders/를 호출하고, 수신 시스템은 없는 속성에 대해서는 전혀 언급하지 않는 오류를 반환합니다.
  • Groovy 스크립트에서는 message.getHeader("orderId", String)가 null을 반환하고, 스크립트는 나중에 널 포인터 오류로 실패하거나 페이로드에 null이라는 텍스트를 씁니다.

흔한 원인

  • 오타 또는 속성 이름의 대소문자 오류: exchange property 이름은 대소문자를 구분하므로 orderID와 orderId는 서로 다른 속성입니다. header 이름은 구분하지 않습니다.
  • 불필요한 공백. 예: ${header.orderId }. 공백이 포함된 이름은 다른 이름입니다.
  • Router의 한 경로에서만 설정한 값을 경로가 다시 합쳐진 뒤에 읽는 경우.
  • 발신자가 보낸 header가 통과되지 않는 경우: HTTPS 발신자는 iFlow의 Runtime Configuration에 있는 Allowed Header(s)에 나열된 사용자 지정 header만 통과시킵니다.
  • 다른 iFlow에서 올 것으로 기대한 속성: exchange property는 ProcessDirect 호출을 넘어가지 않으며, header만 넘어갑니다(ProcessDirect와 JMS 글 참고).
  • header 행이 같은 Content Modifier에서 설정한 속성을 읽는 경우. Content Modifier는 header 테이블을 속성 테이블보다 먼저 처리합니다.

값이 없으면 눈에 보이게 실패시키기

플로가 동작하는 데 꼭 필요한 값이라면, 세 단계 뒤가 아니라 그 값이 필요한 지점에서 실패하게 하세요. 플로 시작 부분에 짧은 Groovy 단계 하나면 충분합니다.

import com.sap.gateway.ip.core.customdev.util.Message

def Message processData(Message message) {
    def orderId = message.getProperty("orderId")
    if (orderId == null || orderId.toString().trim().isEmpty()) {
        throw new IllegalStateException("Exchange property orderId is not set")
    }
    return message
}

그러면 메시지는 없는 속성의 이름을 담은 문장과 함께 오류로 끝나며, 이 내용은 메시지 처리 로그에서 확인할 수 있습니다. Router 조건에서는 기본 경로에 분명한 역할을 주세요. 어떤 경로에도 해당하지 않는 상황이 있어서는 안 된다면, 대비용으로 만든 경로로 메시지를 계속 보내지 말고 Error End 이벤트로 끝내세요.

테스트하는 동안에는 iFlow의 로그 수준을 Trace로 설정하세요. Trace는 각 단계의 header와 exchange property를 보여 주므로 값이 어디에서 사라지는지 정확히 확인할 수 있습니다.

배포 전 체크리스트

  1. iFlow가 읽는 모든 header와 속성을 나열하세요. 표현식, 조건, 어댑터 필드, 스크립트에 있는 것 모두입니다.
  2. 각각에 대해, 읽는 지점에 도달하는 모든 경로에서 그 값을 설정하는 단계를 찾으세요.
  3. 속성의 대소문자와 공백 여부까지 포함해 정확한 철자를 비교하세요.
  4. 발신자에게서 오는 header는 Allowed Header(s)에 나열되어 있는지 확인하세요.
  5. 다른 iFlow에서 오는 값은 속성이 아니라 header로 전달되는지 확인하세요.

큰 iFlow에서 이 작업을 손으로 하면 시간이 꽤 걸립니다. 그래서 가장 먼저 자동화할 가치가 있는 점검입니다.

문제를 예방하는 이름 짓기 습관

  • camelCase 같은 스타일 하나를 정해 package 안의 모든 header와 속성에 일관되게 사용하세요.
  • 플로 전체가 의존하는 값은 시작 부분 근처의 Content Modifier 하나에서 설정해, 찾아볼 곳을 한 군데로 만드세요.
  • SAP_와 Camel 접두사는 SAP와 Apache Camel에 맡기고, 직접 만드는 이름에는 다른 형태를 쓰세요.
  • 이 iFlow 안에서만 필요한 값에는 속성을, iFlow 밖으로 나가야 하는 값에만 header를 쓰세요.

Camel Simple 표현식에 관한 글에서 이 목록의 각 이름 뒤에 있는 문법을 설명합니다.

Kitegra가 도와주는 방법

브라우저 확장 프로그램 Kitegra는 이 체크리스트를 SAP Integration Suite 디자이너 안에서 실행합니다. Lint 패널은 배포하기 전에 iFlow 어디에서도 설정되지 않는 header와 속성, 닫히지 않은 ${, 표현식 안의 불필요한 공백을 표시합니다.

${ 또는 $를 입력하면 iFlow가 설정한 이름(Groovy 및 JavaScript 스크립트에서 설정한 이름 포함)과 SAP 및 Camel의 표준 header만 제안하므로, 처음부터 오타가 생길 가능성이 줄어듭니다. 일부 경로에서만 설정되는 이름에는 “일부 경로에서만 설정됨”이라고 표시됩니다. 확장 프로그램은 iFlow의 내용을 저장, 배포, 편집하지 않으며, tenant는 이름이 정해진 네 가지 작업 중 하나를 클릭할 때만 바뀝니다. 이 작업들은 끌 수 있습니다.

런타임에 값이 비어 있다면 메시지를 단계별로 트레이스하기에서 각 단계 전의 header와 속성을 확인할 수 있고, iFlow 리뷰 체크리스트에서 그 원인이 되는 설계 실수를 다룹니다.

Kitegra 계정이 없어도 모듈당 5개 iFlow에서 사용할 수 있습니다. Free 요금제는 50개, Starter는 100개, Pro는 300개까지 지원하며 Business는 제한이 없습니다. 요금제 비교하기.

다음 iFlow에서 사용해 보세요

Kitegra가 SAP Integration Suite 디자이너에서 무엇을 하는지 읽어 보거나, Kitegra의 다른 Chrome 확장 프로그램과 함께 살펴보세요.

자주 묻는 질문

header가 없는데 SAP CPI가 오류를 내지 않는 이유는 무엇인가요?

Apache Camel은 존재하지 않는 header나 속성에 대해 빈 값을 반환합니다. 문제는 그 빈 값이 피해를 주는 곳에서만 드러나며, 흔히 몇 단계 뒤입니다.

설정된 것이 보이는데 exchange property가 null인 이유는 무엇인가요?

대소문자를 확인하세요. exchange property 이름은 대소문자를 구분합니다. 또한 그 값을 설정하는 단계가 메시지가 지나간 경로에서 실행되었는지, 그리고 값이 ProcessDirect 호출을 통해 넘어올 것으로 기대한 것은 아닌지도 확인하세요.

발신자가 보낸 header가 iFlow에 도착하지 않는 이유는 무엇인가요?

HTTPS 발신자는 iFlow의 Runtime Configuration에 있는 Allowed Header(s)에 나열된 사용자 지정 header만 통과시킵니다. 그곳에 header 이름을 추가하세요.

각 단계의 header와 속성을 보려면 어떻게 하나요?

iFlow의 로그 수준을 Trace로 설정하고 메시지를 하나 실행하세요. 모니터의 Trace에 각 단계의 header와 exchange property가 표시됩니다.

필수 값이 없을 때 플로를 멈추려면 어떻게 하나요?

값을 확인하고 명확한 메시지와 함께 예외를 던지는 스크립트 단계를 추가하거나, Router의 기본 분기를 Error End 이벤트로 연결하세요.

배포 전에 점검할 수 있나요?

네. iFlow가 읽는 모든 이름을 iFlow가 설정하는 이름과 비교하면 됩니다. Kitegra의 Lint 패널이 디자이너 안에서 이 작업을 합니다.

디자이너를 떠나지 않고 iFlow 작업하기

Kitegra을 Chrome 또는 Microsoft Edge에 추가하세요. 계정 없이 무료로 시작할 수 있습니다.