Zum Inhalt springen
Kitegra
← Zurück zum Blog

Modul in diesem Artikel: Integration Flow Helper

Camel Simple Expressions in SAP CPI: Header, Properties und ${…} mit Beispielen

So funktionieren Camel Simple Expressions in SAP CPI: ${header.x}, ${property.x}, ${in.body}, Datumswerte, die Content-Modifier-Reihenfolge, Router-Bedingungen und Fehler, die nichts liefern.

Camel Simple Expressions in SAP CPI: Header, Properties und ${…} mit Beispielen

Fast jeder dynamische Wert in einem iFlow von SAP Cloud Integration (SAP CPI) wird in der Simple Expression Language von Apache Camel geschrieben: ein Header in einer Receiver-Adresse, eine Property in einem Content Modifier, ein Datum in einem Dateinamen, eine Bedingung in einem Router. Die Syntax ist kurz, ${…}, und ein kleiner Fehler fällt leicht nicht auf.

Dieser Artikel behandelt die Ausdrücke, die Sie täglich brauchen, die Reihenfolge, in der ein Content Modifier sie auswertet, den Unterschied zwischen Headern und Exchange Properties sowie die Fehler, durch die ein Ausdruck stillschweigend nichts zurückgibt.

Was eine Simple Expression in SAP CPI ist

SAP Integration Suite führt jeden iFlow auf Apache Camel aus. Wenn ein Schritt läuft, ersetzt Camel jedes ${…} im Feld durch einen Wert aus der aktuellen Nachricht: einen Header, eine Exchange Property, den Body oder eine eingebaute Funktion wie das aktuelle Datum. Der Text um den Ausdruck herum bleibt unverändert, sodass aus Order-${header.orderId}.xml die Datei Order-4711.xml wird.

Simple Expressions können Sie in Content-Modifier-Werten vom Typ Expression und im Message Body schreiben, in den Adress- und Query-Feldern vieler Receiver-Adapter, in Router- und Filter-Bedingungen vom Typ Non-XML sowie in Feldern wie einem Mail-Betreff oder einem SFTP-Dateinamen. Externalisierte Parameter sehen ähnlich aus, sind aber etwas anderes: {{receiverHost}} wird einmal beim Deployment des iFlows ersetzt, während ${…} für jede Nachricht ausgewertet wird.

Die Ausdrücke für den Alltag

Eine Handvoll Ausdrücke deckt die meisten iFlows ab, und sie lassen sich frei mit normalem Text kombinieren. Ein Content-Modifier-Body kann zum Beispiel ein ganzes XML-Dokument aus Headern, Properties und Funktionen aufbauen:

<Order>
  <Id>${property.orderId}</Id>
  <Customer>${header.customerId}</Customer>
  <ReceivedOn>${date:now:yyyy-MM-dd}</ReceivedOn>
  <Flow>${camelId}</Flow>
  <MessageLog>${property.SAP_MessageProcessingLogID}</MessageLog>
</Order>
AusdruckWas er zurückgibt
${header.orderId}Den Message Header orderId
${property.orderId}Die Exchange Property orderId (Camel akzeptiert auch ${exchangeProperty.orderId})
${in.body} oder ${body}Den aktuellen Message Body als Text
${date:now:yyyy-MM-dd}Das heutige Datum im angegebenen Java-Datumsmuster
${camelId}Den Namen des laufenden Integration Flows
${property.SAP_MessageProcessingLogID}Die ID des aktuellen Message Processing Logs
${header.CamelHttpResponseCode}Den Statuscode des letzten HTTP-Aufrufs

Wie ein Content Modifier Header, Properties und Body auswertet

Ein Content Modifier arbeitet seine Registerkarten in fester Reihenfolge ab: zuerst die Tabelle Message Header, dann die Tabelle Exchange Property, dann den Message Body. Innerhalb jeder Tabelle laufen die Zeilen von oben nach unten.

Diese Reihenfolge bestimmt, was ein Ausdruck sieht. Eine Property-Zeile kann einen Header lesen, der weiter oben im selben Content Modifier angelegt wurde, und der Body kann beides verwenden. Eine Header-Zeile kann dagegen keine Property lesen, die derselbe Content Modifier anlegt, denn die Property existiert noch nicht, wenn der Header ausgewertet wird; sie liest stattdessen einen leeren Wert. Wenn Sie das brauchen, setzen Sie die Property in einem früheren Content Modifier oder verschieben Sie den Wert in die Header-Tabelle darüber.

  • Quelltyp Expression: Der Wert ist eine Simple Expression, zum Beispiel ${date:now:yyyyMMdd}-${header.orderId}.
  • Quelltyp Header oder Property: kopiert einen anderen Header oder eine andere Property über den Namen, ohne ${…} darum.
  • Quelltyp XPath: liest einen Wert aus einem XML-Body (siehe den unten verlinkten XPath-Artikel).
  • Die Quelltypen Constant, Local Variable, Global Variable und Number Range decken feste und gespeicherte Werte ab.

Header oder Exchange Properties: was Sie wann verwenden

Ein Header reist mit der Nachricht. Receiver-Adapter können Header an das aufgerufene System weitergeben, und Header gelangen über einen ProcessDirect-Aufruf in einen anderen iFlow. Eine Exchange Property bleibt im Exchange des aktuellen iFlows und wird nie von sich aus an einen Receiver gesendet.

Zwei Details sorgen für die meisten Überraschungen. Header-Namen unterscheiden nicht zwischen Groß- und Kleinschreibung, daher lesen ${header.OrderID} und ${header.orderid} denselben Header. Namen von Exchange Properties tun das sehr wohl, daher sind ${property.OrderID} und ${property.orderId} zwei verschiedene Properties, und die zweite existiert womöglich gar nicht.

  • Verwenden Sie eine Property für Werte, die nur dieser iFlow braucht: IDs, Zähler, Flags, gesicherte Kopien der Payload.
  • Verwenden Sie einen Header für Werte, die ein Adapter oder der nächste iFlow erhalten muss, und entfernen Sie Header, die den Tenant nicht verlassen sollen.
  • Halten Sie große Werte aus Headern heraus: Sie werden bei jedem Aufruf mitgeschickt.

Simple-Bedingungen in Router und Filter

In einer Router-Route oder einem Filter vom Typ Non-XML ist die Bedingung eine Simple Expression, die mit einem Wert verglichen wird. Die üblichen Operatoren sind =, !=, >, >=, <, <=, contains, in und regex, verknüpft mit and oder or. Textwerte stehen in einfachen Anführungszeichen:

${header.orderType} = 'EXPRESS'
${property.amount} > 1000 and ${header.country} in 'DE,AT,CH'
${header.CamelHttpResponseCode} != '200'

Existiert der Header oder die Property in einer Bedingung nicht, ist die Bedingung einfach falsch, und die Nachricht nimmt eine andere Route, oft die Default-Route. Der Artikel über unbekannte Header und Properties zeigt, wie Sie das abfangen, bevor es die Produktion erreicht.

Wie der Kitegra hilft

Der Kitegra ist eine Browser-Erweiterung für den Designer der SAP Integration Suite. Tippen Sie ${ oder $ in ein Feld des Designers, und er listet die Namen, die an dieser Stelle des iFlows passen: Header und Properties aus Content Modifiern, aus Groovy- und JavaScript-Skripten und von anderen Stellen im iFlow, Standard-Header und -Ausdrücke von SAP und Camel, {{…}}-Parameter, Variablen und Data-Store-Namen. Ein Name, der nur auf manchen Pfaden gesetzt wird, ist mit „Nur auf einigen Pfaden gesetzt“ markiert.

Sein Lint-Bereich meldet ein nicht geschlossenes ${, überzählige Leerzeichen in einem Ausdruck sowie Header und Properties, die nirgends im iFlow gesetzt werden. Für XPath-Zeilen liefert eine Beispiel-Payload zusätzlich Pfadvorschläge, wie der XPath-Artikel erklärt. Die Erweiterung speichert, deployt oder bearbeitet nie den Inhalt eines iFlows, und Ihr Tenant ändert sich nur, wenn Sie auf eine von vier benannten Aktionen klicken, die sich abschalten lassen.

Um zu sehen, welche Werte Ihre Ausdrücke wirklich liefern, tracen Sie eine Nachricht Schritt für Schritt und lesen Sie die Header und Properties vor jedem Schritt.

Ohne Kitegra-Konto funktioniert sie für 5 iFlows je Modul. Der Tarif Free umfasst 50, Starter 100 und Pro 300. In den Team-Tarifen erhält jedes Mitglied Pro, mit 300 iFlows je Modul in Startup Team und ohne Limit in Growth Team und Scale Team. Während des Starts von Kitegra sind alle Werkzeuge für alle Angemeldeten offen, auch im Tarif Free. Tarife vergleichen.

Probieren Sie ihn im nächsten iFlow aus

Lesen Sie, was der Kitegra im Designer der SAP Integration Suite leistet, oder sehen Sie ihn neben den anderen Chrome-Erweiterungen von Kitegra.

Häufige Fragen

Was ist der Unterschied zwischen ${header.x} und ${property.x} in SAP CPI?

${header.x} liest einen Message Header, der mit der Nachricht reist und Receiver sowie andere iFlows erreichen kann. ${property.x} liest eine Exchange Property, die im aktuellen iFlow bleibt.

Wird bei Header- und Property-Namen zwischen Groß- und Kleinschreibung unterschieden?

Bei Header-Namen nicht: ${header.OrderID} und ${header.orderid} lesen denselben Header. Bei Namen von Exchange Properties schon, daher sind ${property.OrderID} und ${property.orderId} verschiedene Properties.

Warum ist mein Header leer, wenn ich ihn aus einer Property im selben Content Modifier setze?

Ein Content Modifier wertet zuerst die Header-Tabelle aus, dann die Property-Tabelle, dann den Body. Ein Header kann keine Property lesen, die im selben Schritt angelegt wird; setzen Sie die Property in einem früheren Schritt.

Wie bringe ich das heutige Datum in einen Dateinamen oder ein Feld?

Verwenden Sie ${date:now:yyyy-MM-dd} mit einem beliebigen Java-Datumsmuster, zum Beispiel ${date:now:yyyyMMddHHmmss} für einen Zeitstempel.

Ist {{parameter}} eine Simple Expression?

Nein. {{…}} kennzeichnet einen externalisierten Parameter, der einmal beim Deployment des iFlows ersetzt wird. ${…} wertet Camel für jede Nachricht aus.

Was passiert, wenn ein Ausdruck einen Header nennt, der nicht existiert?

Er gibt ohne Fehler einen leeren Wert zurück, sodass sich das Problem erst später als falsche Route oder leeres Feld zeigt. Eine Lint-Prüfung oder ein Absicherungsschritt fängt es früher ab.

Arbeiten Sie an iFlows, ohne den Designer zu verlassen

Fügen Sie Kitegra zu Chrome oder Microsoft Edge hinzu. Kostenlos starten, ohne Konto.