Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
Showing results for 
Search instead for 
Did you mean: 
Active Contributor


While working on CPI developments, you would inevitably have come across Camel's Simple Expression Language. Whether you use it consciously or not, its presence is pervasive in most CPI integration flows, within elements like Content Modifier, Router, and many others. If you have not already recognised it, any dynamic placeholder using ${ } is essentially a Simple expression.


Get to know Camel’s Simple expression language in HCI by 7a519509aed84a2c9e6f627841825b5a, as the title suggests is an excellent read to know more about Simple.


Simple meets Groovy

While Simple meets a lot of simple needs in CPI, Groovy scripting is still the way if you need more muscle power.


But what if you want to use Groovy and still leverage some of the built-in expressions that are already available in Simple. Meet SimpleBuilder, a Java-based API that is part of the Camel framework, which can be used to evaluate Simple expressions.


The most straightforward way to use the API is to first instantiate a SimpleBuilder object providing the expression to be evaluated.
SimpleBuilder builder = SimpleBuilder.simple('${camelId}')

The example above uses ${camelId} to retrieve the name of the CamelContext.


Subsequently, the expression is evaluated and the value is returned as a String.
String result = builder.evaluate(exchange, String)


Pretty simple (no pun intended) isn't it?


Not exactly - notice that the evaluate() method requires an Exchange object as one of the input. Within a CPI Groovy script (sample below), you do not have direct access to the exchange, but only the Message object.
def Message processData(Message message) {
// enter code here
return message


It's not a bug, it's a feature

If you managed to get a hold of the library file containing (maybe you bothered to read about it here), you might notice that the implementing class of the Message interface contains the Exchange object as one of its instance attributes.


Unfortunately, it is a private instance attribute, so you can't really do much about it.


Or, can you??!!


One of the quirky things about Groovy is that it ignores the access modifier attributes. In layman terms, you can access private attributes from Groovy!


Whether it is a bug or a feature, I'll leave that to you to debate and decide.


Moving on, this means we can access the exchange with just the code below (using Groovy's dot notation):-
Exchange exchange =


Putting it together

Okay, let's put it all together and see what we can make out of it.


We put together all the logic into the following sample script and implement it in a CPI integration flow. The main intent is to evaluate a few built-in Simple expressions, and populate it into the message body.


Note: It is important that the Simple expressions be encapsulated in single quotes so that it is passed as-is. Using double quotes will cause them to be interpreted as GStrings (yes, they are really called that in Groovy!) rather than Simple expressions.
import org.apache.camel.Exchange
import org.apache.camel.builder.SimpleBuilder

def Message processData(Message message) {
Exchange ex =
StringBuilder sb = new StringBuilder()

def evaluateSimple = { simpleExpression ->
SimpleBuilder.simple(simpleExpression).evaluate(ex, String)

sb << 'Camel ID: ' + evaluateSimple('${camelId}') + '\r\n'
sb << 'Exchange ID: ' + evaluateSimple('${exchangeId}') + '\r\n'
sb << evaluateSimple('${messageHistory}') + '\r\n'

return message


Once we execute the integration flow, the following content will be displayed in the message body. Noticed that we are now able to retrieve the details for the Camel ID, Exchange ID as well as the Message History.
Camel ID: CPI_SimpleBuilder
Exchange ID: ID-vsa3637487-43346-1521314171141-295-2

Message History
RouteId ProcessorId Processor Elapsed (ms)
[Process_1 ] [Process_1 ] [sap-http:/simple ] [ 73]
[Process_1 ] [to10801 ] [sap-pp-util://sender ] [ 1]
[Process_1 ] [removeHeaders295 ] [removeHeaders[*] ] [ 0]
[Process_1 ] [CallActivity_1_152] [setHeader[scriptFile] ] [ 2]
[Process_1 ] [setHeader28418 ] [setHeader[scriptFileType] ] [ 0]
[Process_1 ] [bean5828 ] [bean[ref:scriptprocessor method:process] ] [ 63]

Exchange[###REPLACE_ME### Id ID-vsa3637487-43346-1521314171141-295-2###REPLACE_ME### ExchangePattern InOut###REPLACE_ME### Headers {CamelHttpMethod=GET, CamelHttpPath=, CamelHttpQuery=null, CamelHttpUrl=, CamelServletContextPath=/simple, SAP_MessageProcessingLogID=AFrFfk8uQihDbdRTlyZEiOZd7qvr, scriptFile=simple.groovy, scriptFileType=groovy}###REPLACE_ME### BodyType Body [Body is not logged]]



This illustrates the possibility of combining both Simple and Groovy together in a CPI development.

The initial driver behind this was the need to access Camel's Message History. When the integration flow becomes more complex, the traversal path and point of failure are not always immediately visible. This could also be achieved with a Content Modifier with the relevant Simple expressions followed by a Groovy script, but I wanted to combine them in a single step.Fortunately, such custom development is no longer required since a similar looking history has now been introduced for troubleshooting messages in WebUI.

One last note of caution regarding the bug/feature of Groovy - as always, use such undocumented feature wisely especially in a productive environment.
Labels in this area