Skip to Content
Author's profile photo Eng Swee Yeoh

Modularising CPI Groovy scripts using POGO

Introduction

As with any programming language, the aim is to always modularise the code so that it can be “written once, and used in many places”.

This is no different in CPI where one of the two scripting languages available is Groovy. While it is very easy to create Groovy scripts in CPI, when the integration flow becomes more complex, inevitably there may be occasions where the same logic is repeated in different scripts. This presents an opportunity to modularise and simplify the development.

One approach to perform such modularisation is by using Plain Old Groovy Objects (POGO), which are the Groovy equivalent of POJO. In short, they are just Groovy classes as opposed to the Groovy scripts that are typically generated by the CPI development tools.

 

Where is my package?

If you are one of those who have already fully jumped onto the WebUI bandwagon, it might not be that obvious how this can be performed or achieved. This is because every class needs to belong to a package, but when you develop in WebUI, the structure of the project is not visible.

Have no fear, Eclipse to the rescue!

Just create a dummy integration project in Eclipse, and you can see the project structure. Groovy scripts typically are automatically created in the src.main.resources.script folder, so this would be a good choice for our POGO’s package.

 

Sample POGO

Following is a sample of a simple Groovy class (named MessageHelper) containing the following commonly used logic in CPI:-

  • Retrieving content from a message header
  • Logging content into the Message Processing Log’s attachment
package src.main.resources.script

import com.sap.gateway.ip.core.customdev.util.Message
import com.sap.it.api.msglog.MessageLogFactory

class MessageHelper {
	Message msg
	MessageLogFactory logFactory
	
	String getHeaderValue(String headerName, String defaultValue) {
		def headerValue = this.msg.getHeaders()[headerName]
		if(headerValue)
			headerValue
		else if(defaultValue)
			defaultValue
		else
			throw new RuntimeException("Header $headerName do not exist")
	}
	
	String getHeaderValue(String headerName) {
		getHeaderValue(headerName, null)
	}
	
	void logToMPL(String logName, String content) {
		def messageLog = this.logFactory.getMessageLog(this.msg)
		if (messageLog) {
			messageLog.addAttachmentAsString(logName, content, "text/plain")
		}
	}
}

 

With the Groovy code in place, you just need to place them into the Integration Project. With Eclipse, it is just as easy as creating a Groovy class in the right package folder.

However, if you are working in WebUI, the following current limitations necessitate a slightly different approach:-

  • Groovy source codes can only be created via a new Groovy Script step (cannot be independently created in the project)
  • Groovy scripts are automatically named scriptN.groovy, and cannot be renamed.

As such, it is better to create the source code (either the full logic or just a skeleton) with the appropriate class name, and upload it using the Resources Management functionality of the WebUI.

 

Using our new POGO

To use our new POGO, we can simply have an integration flow with a Groovy script as shown below.

 

Following is the sample logic of the script. Take note that it is important to declare the import statement for the above created class.

Note how the modularisation has significantly simplified the logic required to retrieve a header value and log it into the MPL.

import com.sap.gateway.ip.core.customdev.util.Message
import src.main.resources.script.MessageHelper

def Message processData(Message message) {
    MessageHelper helper = new MessageHelper(msg: message, logFactory: messageLogFactory)
    def httpMethod = helper.getHeaderValue('CamelHttpMethod')
    
    helper.logToMPL('Header Details', "Value of CamelHttpMethod is $httpMethod")
    
    return message
}

 

And when we run a sample test, voila, it produces the expected results.

 

Conclusion

While Groovy provides a delightful scripting environment to implement custom logic in CPI, do be cautious in creating too many scripts that have significant portions that are copied from another script.

Be diligent in simplifying and modularising to achieve a lean and clean development.

Assigned Tags

      10 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Naresh Dasika
      Naresh Dasika

      Nice blog Eng Swee:)

      This way integration developers can reduce the complexity of the groovy scripts by placing the common logics under one package.

      Author's profile photo Richard Spinks
      Richard Spinks

      A blog worth bookmarking.

      I've copied and pasted way too many Groovy scripts and will find this much neater and more efficient.

      Thank you for sharing.

      Author's profile photo Michelle Crapo
      Michelle Crapo

      Nice one! I love easy to read instructions.

      Michelle

       

      Author's profile photo Former Member
      Former Member

      Hi Eng Swee,

      Good one, Nice blog with clear instructions.

      Praveen

      Author's profile photo Harsh Bhatt
      Harsh Bhatt

      Hi Eng Swee,

       

      Good one, this way we can have some structure in the groovy mess 🙂

       

      Thanks,

      Harsh

      Author's profile photo PANAGIOTIS PAPADOPOULOS
      PANAGIOTIS PAPADOPOULOS

      Hello Eng Swee,

      Thanks for the Blog. I have the following question:

      Does the "Upload Resource" take place in each Integration flow in which we need to use the script ?

      If we have to make a change to the script, do we have to upload it again to all the Integration flows ?

      Author's profile photo Tang Lambert
      Tang Lambert

      Nice blog

      Author's profile photo Jeffrey Seltmann
      Jeffrey Seltmann

      Found this article today and I am unable to get the "import src.main.resources.script.xxx" to work correctly.  I have uploaded my groovy script with the class name etc.  Any help?

      Author's profile photo Shanmukha Siddartha Cherukumudi
      Shanmukha Siddartha Cherukumudi

      Hi,

      I am having an issue importing the classes if in case there are multiple classes present in my single groovy script file. But the Groovy Language as such supports it

       

      Is it a limitation in the SAP CPI

      Kindly let me know

      Author's profile photo Tomasz Mosko
      Tomasz Mosko

      How to use a Groovy class that is referenced in Resources->References?