Перейти к содержимому
Kitegra
← Вернуться в блог

Модуль в этой статье: Integration Flow Helper

Неизвестные headers и свойства в SAP CPI: найдите их до тихого сбоя

Почему опечатка или отсутствие header или exchange property в SAP CPI не вызывает ошибки, типичные причины и как найти такие имена при проектировании и во время выполнения.

Неизвестные headers и свойства в SAP CPI: найдите их до тихого сбоя

Header, который нигде не задан, не останавливает iFlow в SAP CPI. Выражение, которое его читает, возвращает пустое значение, условие Router становится ложным, поле payload остаётся пустым, а сообщение идёт дальше. Ошибка, если она вообще будет, появится через несколько шагов или в системе-получателе.

В этой статье объясняется, почему отсутствующие headers и exchange properties дают тихий сбой, какие причины повторяются снова и снова и какие проверки находят их раньше, чем сообщение.

Почему отсутствующее имя не вызывает ошибку

Apache Camel считает несуществующий header или свойство пустым значением, а не ошибкой. Это удобно для необязательных значений — и именно поэтому опечатка может месяцами жить в iFlow. Что вы увидите, зависит от того, где читается имя:

  • Значение Content Modifier вроде ${property.orderId} превращается в пустую строку.
  • Условие Router или Filter вроде ${header.orderType} = 'EXPRESS' вычисляется как ложное, и сообщение уходит по другой ветке, часто по ветке по умолчанию.
  • Адрес получателя вроде /orders/${property.orderId} вызывает /orders/, и система-получатель отвечает ошибкой, в которой отсутствующее свойство не упоминается.
  • В скрипте Groovy message.getHeader("orderId", String) возвращает null, и скрипт позже падает с ошибкой null pointer или записывает текст null в payload.

Типичные причины

  • Опечатка или неверный регистр в имени свойства: имена exchange properties чувствительны к регистру, поэтому orderID и orderId — два разных свойства. Имена headers к регистру не чувствительны.
  • Лишний пробел, например ${header.orderId }: имя с пробелом — это другое имя.
  • Значение, заданное только в одной ветке Router и читаемое после того, как ветки снова сходятся.
  • Header, который отправляет вызывающая сторона, но который не пропускается: отправитель HTTPS пропускает только пользовательские headers, перечисленные в Allowed Header(s) в Runtime Configuration iFlow.
  • Свойство, которое ожидается из другого iFlow: exchange properties не передаются через вызов ProcessDirect, передаются только headers (см. статью о ProcessDirect и JMS).
  • Строка header, читающая свойство, созданное в том же Content Modifier, который обрабатывает таблицу headers раньше таблицы свойств.

Пусть отсутствующее значение падает заметно

Для значений, без которых поток не может работать, прерывайте обработку там, где они нужны, а не тремя шагами позже. Достаточно короткого шага 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 показывает headers и exchange properties на каждом шаге, поэтому видно, где именно пропадает значение.

Чек-лист перед развёртыванием

  1. Перечислите все headers и свойства, которые читает iFlow: в выражениях, условиях, полях адаптеров и скриптах.
  2. Для каждого найдите шаг, который его задаёт, на каждом пути, ведущем к месту чтения.
  3. Сравните точное написание, включая регистр у свойств и любые пробелы.
  4. Для headers, приходящих от отправителя, проверьте, что они указаны в Allowed Header(s).
  5. Для значений, приходящих из другого iFlow, проверьте, что они передаются как headers, а не как свойства.

Вручную такая проверка большого iFlow занимает немало времени — поэтому её стоит автоматизировать в первую очередь.

Привычки именования, которые предотвращают проблему

  • Выберите один стиль, например camelCase, и используйте его для всех headers и свойств в пакете.
  • Задавайте значения, от которых зависит весь поток, в одном Content Modifier в начале, чтобы искать их в одном месте.
  • Оставьте префиксы SAP_ и Camel для SAP и Apache Camel; своим именам дайте другую форму.
  • Используйте свойства для значений, нужных только этому iFlow, а headers — только для значений, которые должны его покинуть.

В статье о выражениях Camel Simple объясняется синтаксис, стоящий за каждым именем в этом списке.

Чем помогает Kitegra

Расширение браузера Kitegra выполняет этот чек-лист прямо в дизайнере SAP Integration Suite. Его панель lint ещё до развёртывания отмечает headers и свойства, которые ничто в iFlow не задаёт, незакрытый ${ и лишние пробелы в выражениях.

Когда вы вводите ${ или $, оно предлагает только имена, которые задаёт iFlow, включая заданные в скриптах Groovy и JavaScript, плюс стандартные headers SAP и Camel, так что опечатка менее вероятна с самого начала. Имя, которое задаётся только на части путей, помечается как «Задаётся только на некоторых путях». Расширение никогда не сохраняет, не развёртывает и не редактирует содержимое iFlow, а ваш tenant меняется только тогда, когда вы нажимаете одно из четырёх названных действий, и их можно отключить.

Если значение пусто во время выполнения, пошаговая трассировка сообщения покажет headers и свойства перед каждым шагом, а чек-лист ревью iFlow разбирает ошибки дизайна, которые к этому приводят.

Без аккаунта Kitegra расширение работает на 5 iFlow в каждом модуле. Тариф Free охватывает 50, Starter — 100, Pro — 300; в Business ограничений нет. Сравните тарифы.

Попробуйте в следующем iFlow

Узнайте, что делает Kitegra в дизайнере SAP Integration Suite, или посмотрите его рядом с другими расширениями Kitegra для Chrome.

Частые вопросы

Почему SAP CPI не выдаёт ошибку, когда header отсутствует?

Apache Camel возвращает пустое значение для несуществующего header или свойства. Проблема проявляется только там, где пустое значение причиняет вред, часто через несколько шагов.

Почему моё exchange property равно null, хотя я вижу, где оно задаётся?

Проверьте регистр: имена exchange properties к нему чувствительны. Убедитесь также, что задающий его шаг выполняется на пути, по которому прошло сообщение, и что значение не ожидалось через вызов ProcessDirect.

Почему header, который отправляет вызывающая сторона, не доходит до моего iFlow?

Отправитель HTTPS пропускает только пользовательские headers, перечисленные в Allowed Header(s) в Runtime Configuration iFlow. Добавьте туда имя header.

Как увидеть headers и свойства на каждом шаге?

Установите уровень журналирования iFlow в Trace и пропустите сообщение. Trace в мониторе показывает headers и exchange properties каждого шага.

Как остановить поток, если обязательное значение отсутствует?

Добавьте шаг скрипта, который проверяет значение и выбрасывает исключение с понятным сообщением, или направьте ветку Router по умолчанию в событие Error End.

Можно ли проверить это до развёртывания?

Да, сравнив каждое имя, которое читает iFlow, с именами, которые он задаёт. Панель lint в Kitegra делает это в дизайнере.

Работайте с iFlows, не покидая дизайнер

Добавьте Kitegra в Chrome или Microsoft Edge. Начните бесплатно, без аккаунта.