Most SAP Cloud Integration (CPI) iFlows can be built with standard steps: content modifiers, mappings, routers and adapters. But sooner or later you need a Groovy script. After about three years of CPI work, these are the six snippets I keep coming back to.
1. The basic skeleton: headers, properties and body
Every script starts here. Read what you need, set what the next step needs, return the message.
import com.sap.gateway.ip.core.customdev.util.Message
def Message processData(Message message) {
def body = message.getBody(String)
def orderId = message.getProperty("orderId")
message.setHeader("X-Order-Id", orderId)
message.setProperty("payloadLength", body?.length() ?: 0)
return message
}
Rule of thumb: use properties for values that stay inside the iFlow, and headers for values that must travel to a receiver adapter.
2. Parse and build JSON without a mapping
For small JSON reshaping, JsonSlurper + JsonOutput is often simpler than a full message mapping.
import com.sap.gateway.ip.core.customdev.util.Message
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
def Message processData(Message message) {
def input = new JsonSlurper().parse(message.getBody(java.io.Reader))
def output = [
customerId: input.customer?.id,
total : input.items?.sum { it.price * it.qty } ?: 0,
itemCount : input.items?.size() ?: 0
]
message.setBody(JsonOutput.toJson(output))
message.setHeader("Content-Type", "application/json")
return message
}
3. Log the payload, but only when you ask for it
Attaching payloads to the Message Processing Log (MPL) is the fastest way to debug. Leaving it on in production fills up storage and can expose personal data. I control it with an externalized parameter.
import com.sap.gateway.ip.core.customdev.util.Message
def Message processData(Message message) {
def enabled = message.getProperty("enablePayloadLogging")
if ("true".equalsIgnoreCase(enabled as String)) {
def log = messageLogFactory.getMessageLog(message)
log?.addAttachmentAsString("Payload", message.getBody(String), "text/plain")
}
return message
}
Set enablePayloadLogging in a Content Modifier from an externalized parameter, so you can switch it on in the tenant without redeploying a new version.
4. Read a Value Mapping from a script
When a lookup depends on runtime logic, you can call the Value Mapping API directly.
import com.sap.gateway.ip.core.customdev.util.Message
import com.sap.it.api.ITApiFactory
import com.sap.it.api.mapping.ValueMappingApi
def Message processData(Message message) {
def vm = ITApiFactory.getService(ValueMappingApi.class, null)
def plant = message.getProperty("sourcePlant")
def target = vm.getMappedValue("SAP_ERP", "Plant", plant, "WMS", "Warehouse")
message.setProperty("targetWarehouse", target ?: "UNMAPPED")
return message
}
Always handle the null case. A missing entry should fail clearly, not send an empty value downstream.
5. Fail on purpose with a useful message
If validation fails, throw an exception. The Exception Subprocess catches it, and ${exception.message} gives you a readable reason for alerts or error emails.
import com.sap.gateway.ip.core.customdev.util.Message
def Message processData(Message message) {
def orderId = message.getProperty("orderId")
if (!orderId) {
throw new IllegalStateException("Validation failed: orderId is missing in the inbound payload")
}
return message
}
6. Read the body as a stream, not a String
message.getBody(String) creates a full copy of the payload in memory. For large payloads, pass a Reader straight to the parser instead.
import com.sap.gateway.ip.core.customdev.util.Message
def Message processData(Message message) {
def xml = new XmlSlurper().parse(message.getBody(java.io.Reader))
message.setProperty("recordCount", xml.Record.size())
return message
}
Final tips
- Keep scripts small and single-purpose. Three focused scripts are easier to maintain than one 300-line script.
- Store shared helpers in a Script Collection and reference them from multiple iFlows.
- Test scripts locally or with the CPI simulation feature before deploying.
What Groovy patterns do you rely on in CPI? Share them in the comments.
Top comments (0)