この記事のモジュール: Integration Flow Helper
SAP CPI の未定義 header とプロパティ:黙って失敗する前に見つける方法
SAP CPI で綴りを誤った、または存在しない header や exchange property がエラーなしで失敗する理由、よくある原因、設計時と実行時に見つける方法を解説します。

一度も設定されていない header があっても、SAP CPI の iFlow は止まりません。それを読む式は空の値を返し、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 ポインターエラーで失敗するか、ペイロードに null という文字列を書き込みます。
よくある原因
- タイプミス、またはプロパティ名の大文字と小文字の誤り:exchange property 名は大文字と小文字を区別するため、
orderIDとorderIdは別のプロパティです。header 名は区別しません。 - 余分なスペース。例:
${header.orderId }。スペースを含む名前は別の名前です。 - Router の 1 つのルートでしか設定されない値を、ルートが合流した後で読んでいる。
- 呼び出し元が送る header が通過を許可されていない:HTTPS センダーは、iFlow の Runtime Configuration にある Allowed Header(s) に記載されたカスタム header しか通しません。
- 別の iFlow から届くはずのプロパティ:exchange property は ProcessDirect 呼び出しを越えられず、渡るのは header だけです(ProcessDirect と JMS の記事を参照してください)。
- header の行が、同じ Content Modifier で設定されるプロパティを読んでいる。Content Modifier は header テーブルをプロパティテーブルより先に処理します。
値がないときは目に見える形で失敗させる
フローが動くために欠かせない値については、3 ステップ後ではなく、それが必要になる場所で失敗させましょう。フローの最初に短い 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 が表示されるので、どこで値が消えたのかを正確に確認できます。
デプロイ前のチェックリスト
- iFlow が読むすべての header とプロパティを書き出します。式、条件、アダプターの入力欄、スクリプトの中のものです。
- それぞれについて、読まれる位置に至るすべてのルートで、それを設定するステップを見つけます。
- 正確な綴りを比べます。プロパティの大文字と小文字や、スペースの有無も含めます。
- 送信元から届く header については、Allowed Header(s) に記載されていることを確認します。
- 別の iFlow から届く値については、プロパティではなく header として渡されていることを確認します。
大きな iFlow でこれを手作業で行うとかなりの時間がかかります。だからこそ、真っ先に自動化する価値のあるチェックです。
問題を防ぐ命名の習慣
- camelCase などのスタイルを 1 つ決め、package 内のすべての header とプロパティで統一します。
- フロー全体が依存する値は、先頭近くの 1 つの Content Modifier でまとめて設定し、探す場所を 1 か所にします。
SAP_とCamelの接頭辞は SAP と Apache Camel に任せ、自分の名前には別の形を使います。- この iFlow の中だけで必要な値にはプロパティを使い、header は iFlow の外に出す必要がある値だけに使います。
Camel Simple 式の記事では、このリストにあるそれぞれの名前の背後にある構文を説明しています。
Kitegra でできること
ブラウザー拡張機能 Kitegra は、このチェックリストを SAP Integration Suite のデザイナーの中で実行します。Lint パネルは、iFlow のどこでも設定されていない header とプロパティ、閉じていない ${、式の中の余分なスペースを、デプロイ前に指摘します。
${ または $ と入力すると、iFlow が設定している名前(Groovy と JavaScript のスクリプトで設定されるものを含む)と、SAP と Camel の標準 header だけを候補に出すので、そもそもタイプミスが起きにくくなります。一部の経路でしか設定されない名前には「一部のパスでのみ設定」と表示されます。拡張機能が iFlow の内容を保存、デプロイ、編集することはありません。tenant が変更されるのは、名前の付いた 4 つの操作のいずれかをクリックしたときだけで、これらの操作はオフにすることもできます。
実行時に値が空になっている場合は、メッセージをステップごとにトレースすると各ステップの前の 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 にしてメッセージを 1 件流します。モニターの Trace に、各ステップの header と exchange property が表示されます。
必須の値がないときにフローを止めるにはどうすればよいですか?
値をチェックして、わかりやすいメッセージ付きの例外を投げるスクリプトステップを追加するか、Router のデフォルト分岐を Error End イベントにつなぎます。
デプロイ前にチェックできますか?
できます。iFlow が読むすべての名前を、iFlow が設定する名前と照らし合わせます。Kitegra の Lint パネルがデザイナーの中でこれを行います。