Now accepting guest editorial from SAP, Oracle, Workday and ServiceNow practitioners.Pitch a guide
The Sign-Off Table

Lesson 1 of 6

The script step and the Message object

9 min

Listen to this lesson

0:00 / 6:12

Groovy is Cloud Integration's escape hatch. When a standard step or a graphical mapping can't express a rule, a Script step can. That power has a cost: SAP guarantees only its published script APIs, and you maintain your own code through every runtime upgrade. SAP's guideline is plain: don't use scripts for what standard steps already do, such as splitting or encoding, and prefer mappings and XPath in Content Modifiers over hand-written XML parsing.

At Contoso, Theo's team is moving the 64 integrated configurations off SAP Process Orchestration on XP1. Several of the 12 interfaces marked adapt carry Java user-defined functions or small Java mapping logic that has to become Groovy. This course teaches how to write that Groovy so it survives support, upgrades and audits.

Adding a script

In the palette, choose Message Transformers, then Script, then Groovy Script, and place the step. Create opens the editor with a default script. You can also upload a file, or assign a script from a Script Collection in the Global Resources tab (lesson 5). By default the runtime calls the function processData. If the file has several functions, the Script Function field names the one to call, without arguments.

Groovy script step versionGroovy runtimeWhat it means for you
1.12.4.21Existing scripts; classes such as XmlSlurper come from groovy.util
2.04.0.29SAP's recommended target; some imports change, e.g. groovy.xml.XmlSlurper

Script step versions and Groovy runtimes as documented by SAP. JavaScript steps run on Rhino 1.7.14; both use Java 8 standard libraries.

The editor's Problems view shows an Upgrade Readiness Check (unsupported libraries and classes, unused or duplicate imports) and a General Script Check. Many findings offer Fix. You can still deploy with open findings, but Contoso's rule is to start every migrated script on version 2.0 with a clean Problems view.

The Message object

A script receives the message as an instance of com.sap.gateway.ip.core.customdev.util.Message and returns it. The skeleton is short: import com.sap.gateway.ip.core.customdev.util.Message
def Message processData(Message message) {
  // read, change, set
  return message
}

PartReadWrite
Bodymessage.getBody(String), getBody(java.io.Reader), getBody(java.io.InputStream)message.setBody(newBody)
Headersmessage.getHeaders(), message.getHeader('SapIDocType', String)message.setHeader('SAP_ApplicationID', poNumber)
Propertiesmessage.getProperties(), message.getProperty('poNumber')message.setProperty('lineCount', 3)
Sizemessage.getBodySize()

The Message methods you'll use in almost every script.

Headers or properties?

This is the most important design choice in a script. Headers travel with the message: data written to a header also becomes part of the outbound message to the receiver. Exchange properties stay inside the integration flow and are never handed to a receiver. SAP warns that HTTP receivers often reject large headers, typically somewhere between 4 and 16 KB. So pass values between steps as properties, and use headers only for what the receiver or an adapter should see.

HeaderExchange property
Leaves the flow?Yes, sent with the outbound messageNo, stays inside the integration flow
Typical useSAP_ApplicationID, values an adapter readsPO number, line count, flags between steps
Size riskReceivers may reject large headers (often 4–16 KB)Uses memory, but no receiver limit
Read in a scriptgetHeader(name, String)getProperty(name)
Pass data between steps in properties; use headers only for what should leave the flow.
The Sign-Off Table · thesignofftable.com/academy/sap-pim-202
A script reads and changes the message; properties stay in the flow while headers go out with the message.
The Sign-Off Table · thesignofftable.com/academy/sap-pim-202

Headers the adapters give you

Many values a script needs are already headers. The IDoc sender adapter sets SapIDocType, SapIDocTransferId (the sending system's IDoc number, DOCNUM), SapIDocDbId and SapMessageId. Read them instead of parsing the control record: def idocNo = message.getHeader('SapIDocTransferId', String). One caution from SAP: for a composite (bulk) IDoc message, SapIDocTransferId holds the first IDoc's number only, so read the payload when you need all of them.

Before writing any script, Theo's reviewers ask one question: could a standard step do this? Setting a property from an XPath, deleting headers before a receiver call, splitting a bulk message or converting XML to JSON all have standard steps. Of the scripts found in the 12 adapt interfaces, about half turned into Content Modifier entries during review. The rest became short, tested Groovy.

What would you do?

A developer's script stores the full ORDERS05 payload in a header called <code>originalPayload</code> so a later step can restore it after the mapping. The receiver is a partner's HTTP API. What should the reviewer ask for?

Key points
  • Use scripts only where standard steps and mappings can't do the job; SAP guarantees only its script APIs.
  • Script step 1.1 runs Groovy 2.4.21, version 2.0 runs Groovy 4.0.29; clear the Upgrade Readiness Check.
  • processData(Message) is called by default; the Script Function field picks another function.
  • Headers leave the flow with the message; properties stay inside it.

Check your understanding · not graded

Lesson check

  1. 1. Which Groovy runtime does a Groovy script step at version 2.0 use?

  2. 2. A script must pass the PO number to a later router without sending it to Lakeside. What should it set?

  3. 3. A script file has three functions and none is called processData. How does the step know which to run?

  4. 4. Why does SAP warn about <code>message.getBody(String)</code> on large payloads?