Module de cet article: Integration Flow Helper
Expressions Camel Simple dans SAP CPI : headers, propriétés et ${…} avec exemples
Comment fonctionnent les expressions Camel Simple dans SAP CPI : ${header.x}, ${property.x}, ${in.body}, dates, ordre du Content Modifier, conditions de Router et erreurs qui ne renvoient rien.

Presque toute valeur dynamique d'un iFlow SAP Cloud Integration (SAP CPI) s'écrit dans le langage d'expressions Simple d'Apache Camel : un header dans l'adresse d'un récepteur, une propriété dans un Content Modifier, une date dans un nom de fichier, une condition sur un Router. La syntaxe est courte, ${…}, et il est facile de se tromper légèrement sans s'en apercevoir.
Cet article présente les expressions que vous utiliserez tous les jours, l'ordre dans lequel un Content Modifier les évalue, la différence entre headers et exchange properties, et les erreurs qui font qu'une expression ne renvoie discrètement rien.
Ce qu'est une expression Simple dans SAP CPI
SAP Integration Suite exécute chaque iFlow sur Apache Camel. Lorsqu'une étape s'exécute, Camel remplace chaque ${…} du champ par une valeur du message courant : un header, une exchange property, le body ou une fonction intégrée comme la date du jour. Le texte autour de l'expression reste tel quel, si bien que Order-${header.orderId}.xml devient Order-4711.xml.
Vous pouvez écrire des expressions Simple dans les valeurs de Content Modifier de type Expression et dans le Message Body, dans les champs d'adresse et de requête de nombreux adaptateurs récepteurs, dans les conditions de Router et de Filter de type Non-XML, et dans des champs comme l'objet d'un e-mail ou un nom de fichier SFTP. Les paramètres externalisés se ressemblent mais sont différents : {{receiverHost}} est remplacé une seule fois, au déploiement de l'iFlow, alors que ${…} est évalué pour chaque message.
Les expressions de tous les jours
Une poignée d'expressions couvre la plupart des iFlows, et elles se mêlent librement au texte. Le body d'un Content Modifier peut par exemple construire tout un document XML à partir de headers, de propriétés et de fonctions :
<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>| Expression | Ce qu'elle renvoie |
|---|---|
${header.orderId} | Le header de message orderId |
${property.orderId} | L'exchange property orderId (Camel accepte aussi ${exchangeProperty.orderId}) |
${in.body} ou ${body} | Le body du message courant, sous forme de texte |
${date:now:yyyy-MM-dd} | La date du jour selon le modèle de date Java indiqué |
${camelId} | Le nom de l'integration flow en cours d'exécution |
${property.SAP_MessageProcessingLogID} | L'ID du message processing log courant |
${header.CamelHttpResponseCode} | Le code de statut renvoyé par le dernier appel HTTP |
Comment un Content Modifier évalue headers, propriétés et body
Un Content Modifier traite ses onglets dans un ordre fixe : d'abord la table Message Header, puis la table Exchange Property, puis le Message Body. Dans chaque table, les lignes s'exécutent de haut en bas.
Cet ordre détermine ce qu'une expression peut voir. Une ligne de propriété peut lire un header créé plus tôt dans le même Content Modifier, et le body peut utiliser les deux. Une ligne de header ne peut pas lire une propriété créée par ce même Content Modifier, car la propriété n'existe pas encore au moment où le header est évalué : elle lit une valeur vide. Si vous en avez besoin, définissez la propriété dans un Content Modifier précédent, ou déplacez la valeur dans la table des headers au-dessus.
- Type de source Expression : la valeur est une expression Simple, par exemple
${date:now:yyyyMMdd}-${header.orderId}. - Type de source Header ou Property : copie un autre header ou une autre propriété par son nom, sans
${…}autour. - Type de source XPath : lit une valeur dans un body XML (voir l'article sur XPath, en lien plus bas).
- Les types de source Constant, Local Variable, Global Variable et Number Range couvrent les valeurs fixes et les valeurs stockées.
Headers ou exchange properties : lequel choisir
Un header voyage avec le message. Les adaptateurs récepteurs peuvent transmettre les headers au système appelé, et les headers traversent un appel ProcessDirect vers un autre iFlow. Une exchange property reste dans l'exchange de l'iFlow courant et n'est jamais envoyée d'elle-même à un récepteur.
Deux détails causent la plupart des surprises. Les noms de headers ne sont pas sensibles à la casse : ${header.OrderID} et ${header.orderid} lisent le même header. Les noms d'exchange properties le sont : ${property.OrderID} et ${property.orderId} sont deux propriétés différentes, et la seconde peut tout simplement ne pas exister.
- Utilisez une propriété pour les valeurs dont seul cet iFlow a besoin : IDs, compteurs, indicateurs, copies sauvegardées du payload.
- Utilisez un header pour les valeurs qu'un adaptateur ou l'iFlow suivant doit recevoir, et supprimez les headers qui ne doivent pas quitter le tenant.
- Ne mettez pas de grandes valeurs dans les headers : elles accompagnent chaque appel.
Conditions Simple dans Router et Filter
Dans une route de Router ou un Filter de type Non-XML, la condition est une expression Simple comparée à une valeur. Les opérateurs habituels sont =, !=, >, >=, <, <=, contains, in et regex, combinés avec and ou or. Les valeurs texte s'écrivent entre apostrophes :
${header.orderType} = 'EXPRESS'
${property.amount} > 1000 and ${header.country} in 'DE,AT,CH'
${header.CamelHttpResponseCode} != '200'Si le header ou la propriété d'une condition n'existe pas, la condition est simplement fausse et le message prend une autre route, souvent celle par défaut. L'article sur les headers et propriétés inconnus montre comment le détecter avant la production.
Ce qu'apporte Kitegra
Kitegra est une extension de navigateur pour le designer de SAP Integration Suite. Tapez ${ ou $ dans un champ du designer et elle liste les noms valables à cet endroit de l'iFlow : headers et propriétés définis dans les Content Modifiers, dans les scripts Groovy et JavaScript et ailleurs dans l'iFlow, headers et expressions standard de SAP et de Camel, paramètres {{…}}, variables et noms de Data Store. Un nom défini sur certains chemins seulement est signalé par « Défini sur certains chemins seulement ».
Son panneau de lint signale un ${ non fermé, des espaces en trop dans une expression, et les headers ou propriétés que rien dans l'iFlow ne définit. Pour les lignes XPath, un payload d'exemple fournit aussi des suggestions de chemins, comme l'explique l'article sur XPath. L'extension n'enregistre, ne déploie et ne modifie jamais le contenu d'un iFlow, et votre tenant ne change que lorsque vous cliquez sur l'une de quatre actions nommées, qui peuvent être désactivées.
Pour voir les valeurs que vos expressions produisent réellement, tracez un message étape par étape et lisez les headers et les propriétés avant chaque étape.
Sans compte Kitegra, elle fonctionne sur 5 iFlows par module. Le forfait Free en couvre 50, Starter 100 et Pro 300. Avec les forfaits d'équipe, chaque membre bénéficie de Pro, avec 300 iFlows par module sur Startup Team et sans limite sur Growth Team et Scale Team. Pendant le lancement d'Kitegra, tous les outils sont ouverts à toute personne connectée, y compris avec le forfait Free. Comparez les forfaits.
Essayez-le dans votre prochain iFlow
Découvrez ce que fait Kitegra dans le designer de SAP Integration Suite, ou voyez-le aux côtés des autres extensions Chrome de Kitegra.
Questions fréquentes
Quelle est la différence entre ${header.x} et ${property.x} dans SAP CPI ?
${header.x} lit un header de message, qui voyage avec le message et peut atteindre les récepteurs et d'autres iFlows. ${property.x} lit une exchange property, qui reste dans l'iFlow courant.
Les noms de headers et de propriétés sont-ils sensibles à la casse ?
Pas les noms de headers : ${header.OrderID} et ${header.orderid} lisent le même header. Les noms d'exchange properties le sont : ${property.OrderID} et ${property.orderId} sont des propriétés différentes.
Pourquoi mon header est-il vide quand je le définis à partir d'une propriété du même Content Modifier ?
Un Content Modifier évalue d'abord la table des headers, puis celle des propriétés, puis le body. Un header ne peut pas lire une propriété créée dans la même étape ; définissez la propriété dans une étape précédente.
Comment mettre la date du jour dans un nom de fichier ou un champ ?
Utilisez ${date:now:yyyy-MM-dd} avec n'importe quel modèle de date Java, par exemple ${date:now:yyyyMMddHHmmss} pour un horodatage.
{{parameter}} est-il une expression Simple ?
Non. {{…}} désigne un paramètre externalisé, remplacé une seule fois au déploiement de l'iFlow. ${…} est évalué par Camel pour chaque message.
Que se passe-t-il si une expression nomme un header qui n'existe pas ?
Elle renvoie une valeur vide sans erreur ; le problème apparaît donc plus tard, sous la forme d'une mauvaise route ou d'un champ vide. Une vérification de lint ou une étape de garde le détecte plus tôt.