In this blog post, I will provide some tips and tricks to ease your journey with Cloud Integration.
Prerequisite:
Basic Idea about Cloud Integration and familiarity with integration flow components. For a newbie, developers tutorial could be a good starting point.
Pointers:
1. Header v/s Property in Content Modifier
Header and Property are both named key-value pairs. However, based on the purpose, the decision needs to be taken whether to use Header/Property. If the information needs to be transferred to the receiver system, then ‘Header’ should be used in Content Modifier. If the information is internal to Iflow, then ‘Property’ should be used. The property lasts for the entire duration of an exchange but it is not transferred to a receiver.
For example, Property is best suited if we are trying to fetch Product Id from incoming payload and store it temporarily to use it in a later step within the integration flow.
But, if we want to send standard headers/custom headers to the receiver system, then we can directly use the message header.
2. Order of Message processing in Content Modifier
The order is:
- message header
- exchange property
- message body
For example, if we create a header in Content Modifier and try to access its value in one of the properties in the content modifier, it will be accessible. Similarly, header and properties created in the same content modifier, are also accessible in the message body.
3. Externalized Parameters
Generally, some parameters will change in your iflow based on the environment. For example, the host name of the target system will be different for dev and production. For such cases, we must externalize the parameters.
It removes the need of editing iflows in the production system. Using ‘Configure’ button, we will be able to modify those parameters.
4. Attachment Logging
Generally, if we log request or response payloads as attachments in message processing log, externalized parameters should be defined to disable the same in the production environment.
def Message processData(Message message) {
def body = message.getBody(java.lang.String)
def logProperty = message.getProperty("EnableLogging")
def messageLog = messageLogFactory.getMessageLog(message)
if (messageLog != null && logProperty != null && logProperty.equalsIgnoreCase("TRUE”)) {
messageLog.addAttachmentAsString('Request Body', body, 'text/plain')
}
return message
}
Notice that, in the above code, we are using equalsIgnoreCase() function instead of direct equality operator. It will avoid case comparison of String. Another alternative would be the use of regex expressions.
def logger = (log ==~ /(?i)(true)/)
Here, the expression is used for case insensitive matches.
5. Script Collection
Similarly to the function library in SAP PI/PO, we have script collection in Cloud Integration and we can reuse script across different i-flows. For example, adding custom header in message processing log for source/target filename.
6. Script Function
In Groovy Script, the default function name is processData. However, it can be changed to any name and can be invoked using script function name. It will be useful when we want to keep multiple functions in the same file.
7. JSON Message Mapping
Currently message mapping also supports JSON OAS (Open API Specification) apart from XSD/WSDL. We can use swagger inspector for generating OAS. Please check the steps in the video below.
8. Array in XML to JSON Converter
We can use streaming functionality to convert XML elements to JSON arrays.
Below shows an example of an input XML, where ‘Persons’ is the root node and it may contain one or more ‘Person’ nodes.
<Persons>
<Person>
<Name>Tom</Name>
<Age>18</Age>
</Person>
</Persons>
Now, if we want to convert this to JSON, we will expect the structure to be like below:
{
"Persons": {
"Person": [{
"Name": "Tom",
"Age": "18"
}]
}
}
However, without streaming, the structure will appear as below.
Now, let’s use streaming.
Now the output will look like below
9. Router
Router is similar to the case condition in the programming. Only the 1st match will be executed. So, the order of execution is important here.
For example:
If the payload contains plant number 1102 (1st preference), then it should go to Route 1. If the payload contains plant number 1101, then it should go to Route 2. Else, it will be passed to the default path.
In the sample input payload, 1st record contains plant 1101 and 2nd record contains plant 1102.
10. Determine Error Step
In case of any error, we can utilize the exchange property SAP_ErrorModelStepID, to identify in which step the execution failed and handle the exception based on that. The step Id of a particular step can be found by clicking on the ‘Technical Information’ icon.
11. Exception Subprocess with Error End/Escalated End
Exception subprocess should be ended with an ‘Error End’ event so that messages appear as ‘Failed’ in the message monitoring tab.
Similarly, if we are using JMS as a sender adapter and have put up a condition to end retries after a certain retry count, in that case escalation end is the best choice.
12. Version Control
Using version control, we can revert to the older version. So, it is always recommended to save the changes as a new version.
Reference Links:
Thank you for reading this blog post. Please feel free to share your feedback or thoughts in the comments section or ask any questions in the Q&A tag below.