Get to know Camel’s Simple expression language in HCI
Introduction
Simple is a, well, simple expression language, that ships with the Apache Camel integration framework. The language is also available in HANA Cloud Platform, Integration Service, the product which I will refer to as HCI for the remainder of this blog ????
In HCI, Simple is mainly used to access the contents of the message being processed and its exchange, and to construct condition expressions in the Router step. The language does, however, have a few more tricks up its sleeve.
In this blog I will give you an overview of Simple and its features.
The basics
The most basic Simple expression is the ${ }
placeholder containing a built-in variable. This example expression evaluates to the payload of the input message:
${body}
There is an alternative form, $simple{ }
, which also works in HCI, but I will stick to the ${ }
form in this blog.
In HCI, the ${ }
placeholder can be inserted in e.g. the payload in a Content Modifier step or applied in the Query Editor, adding dynamic values to an OData resource path.
The ${ }
placeholder can also be combined with Simple’s operators to produce boolean expressions, which you can then use as conditions in your Router steps.
Built-in variables
Simple’s built-in variables provide you with access to information such as the message payload and header fields. The list below is not exhaustive. For a list of all built-in variables, please refer to the Simple language documentation. However, keep in mind that not all of them might be supported in HCI.
Variable | Description |
id |
The ID of the message |
exchangeId |
The ID of the exchange |
body |
The payload of the input message |
header.name |
The contents of the named header |
property.name |
The contents of the named exchange property |
date:now:pattern |
The formatted current date and time (more details below) |
random(max) / random(min,max) |
Generates random integers (more details below) |
According to the Simple language documentation, property.name
is actually deprecated. However, the non-deprecated form, exchangeProperty.name
, will cause an error in HCI if used in a Router condition. This will undoubtedly be fixed, but for now you should stick to the deprecated form.
Date and time
The current date and time is available to you in Simple, using the date:now:pattern
variable. The required pattern is a java.text.SimpleDateFormat
date and time pattern string, which you might already be familiar with, if you are a Java developer. Here’s an example:
${date:now:dd-MM-yyyy HH:mm}
At the time of writing, this evaluates to 23-11-2016 06:14. The time is, however, 7:14. What gives? Let’s add the pattern letter z
, in order to see the time zone:
${date:now:dd-MM-yyyy HH:mm z}
This evaluates to 23-11-2016 06:19 UTC. In other words, the time zone is Coordinated Universal Time (UTC).
To learn more about the SimpleDateFormat
pattern strings, please see the class’s API documentation.
Random numbers
Should you need a random number, Simple has you covered by way of the random
variable. There are two ways to employ it:
random(max)
random(min, max)
The first form generates a random integer between 0 (included) and max
(excluded), while the second form generates a random integer between min
(included) and max
(excluded). To generate a random integer between 1 and 10, you would therefore use the following expression:
${random(1, 11)}
Operators
When adding non-XML condition routes to a Router step in your integration flow, you need to construct boolean expressions, i.e. expressions that evaluate to either true or false. The Simple language supports a range of operators, that you can use for this purpose. In the following, I will briefly describe each available operator. For a list of Simple operators supported in HCI at a given time, please refer to SAP’s documentation of the Router step.
When writing your expressions, please be aware that all literal values must be enclosed in single quotes, regardless of data type. Omitting them will cause an error. If required, the data type of the right-hand value will be converted into the data type of the left-hand value. In other words, this is a valid, numeric comparison, even though it looks like a string comparison at first glance:
${property.MyNumericProperty} > '0'
Comparison operators
The Simple language offers you the familiar comparison operators: =
, !=
, >
, >=
, <
and <=
. For some reason, the equality operator in HCI’s version of Simple is a single equals sign, even though it’s a double equals sign in Camel’s Simple language documentation.
Please note that string comparison is case sensitive. There’s actually a case insensitive equals operator in the Simple language (=~
), but at the moment, it is not supported in HCI. In order to compare strings without considering case, you can do this instead:
${property.MyStringProperty.toLowerCase()} = 'lower case value'
For more information about calling methods, see Calling methods.
Logical operators
The two available logical operators are and
and or
. According to the Simple language documentation, the and
and or
forms are actually deprecated, but at the time of writing, the alternative forms (&&
and ||
) are not supported in HCI. Keep in mind, though, that this might very well change in future HCI updates.
You can combine multiple and
and or
operators in the same expression, but you cannot use parentheses for grouping. Consequently, if your boolean expression is long and complex, you are probably better off moving the logic to a Script step instead, for the sake of readability and maintainability.
contains/not contains
The contains
operator tests whether a string contains another string, and not contains
tests whether it doesn’t contain the other string. Here’s an example:
${property.MyStringProperty} contains 'test'
As was the case with string comparison, this operator is case sensitive. To disregard case, convert to upper or lower case by calling toUpperCase()
or toLowerCase()
, respectively.
regex/not regex
Regular expressions are supported in the Simple language via the operators regex
and not regex
. The former tests whether a value matches the provided regular expression, and the latter tests whether it doesn’t match. Here’s an example that tests whether a product code is formatted as five lower-case letters followed by three digits:
${property.ProductCode} regex '^[a-z]{5}d{3}$'
in/not in
The in
operator tests whether a given value occurs in a list of values, and the not in
operator tests whether it doesn’t occur in the list. Here’s an example:
${property.MyNumericProperty} in '1,2,3,4,5'
Note how the entire list in enclosed in single quotes, and how the elements are separated by commas with no whitespace around them. The data type of the list elements will automatically be converted into the data type of the left-hand side value.
When evaluating strings, keep in mind that the comparison is case sensitive. To disregard case, convert the left-hand side to upper or lower case first:
${property.MyStringProperty.toLowerCase()} in 'abc,def'
Calling methods
As we saw in the above with the toLowerCase()
method of Java class String
, you can call methods on objects in your expressions using the familiar dot notation.
Simple provides this functionality by supporting a subset of another Apache language called OGNL. Here’s an example:
${property.MyStringProperty.substring(0,4)} = 'test'
Here, the substring
method of class String
is called, and two integer parameters are passed to the method.
For straightforward method calls with scalar parameters, this works well. However, if your method invocation is more complicated, e.g. if it requires creating and passing objects to the method, moving it to a Script step is the way to go.
Also, there is a special case you need to be aware of: Examples will show method calls without parentheses, and if you are calling a method that doesn’t take any parameters, you don’t need them, unless the method is overloaded. When calling an overloaded method that takes no parameters, you need to append a pair of empty parentheses. Otherwise the call will be ambiguous, and you will end up with a runtime error.
New NetWeaver Information at SAP.com
Very Helpfull