Skip to Content
Technical Articles

Understanding Groovy Scripting for SAP Integration Suite – Part 2

< Part 1

I initially created Part 1 of this blog for beginners to have basic understanding of Groovy Scripting.  I suggest to refer previous part to have better understanding on later part.

Assuming you have been through Part 1 of the blog, and you have basic understanding of coding syntax etc. Here, we will try to understand Groovy Scripting with the help of couple of sample codes achieved in 2 different ways.

As per CPI, Message Mapping supports scripts containing any of the following function signatures

  1. def String customFunc(String arg1) {…}
  2. def String customFunc1(String P1,String P2,MappingContext context) {…}
  3. def void custFunc2(String[] is,String[] ps, Output output, MappingContext context) {…}
  4. def void customFunc3(String[] input1, String[] input2, Output output) {…}

Example 1

Type 1 Coding

import com.sap.it.api.mapping.*;

def String ExistsAndHasValue(String Input)
{
       if (Input != null && Input.trim().length() > 0)
       {
             return true
       }
       else
       {
            return false
       }
}

Type 2 Coding

import com.sap.it.api.mapping.*;

def void ExistsAndHasValue(String[] Input, Output output)
{
    for(int i=0; i<Input.size(); i++)
    {
       if (Input[i] != null && Input[i].trim().length() > 0)
       {
            output.addValue("true")
       }
       else
       {
            output.addValue("false")
       }
    }
}

Sample Input & Output

Understanding Scripts

Both the types of codes gives the same output as shown above. The codes vary in following ways-

Type 1 code working

Function is defined with single parameter and with return type String.

def String ExistsAndHasValue(String Input)

Further, function takes 1 input string at a time to process, for eg. 20210801 of 1st context. checks if it is null or empty value, and then returns true of false respectively. Next it takes 20210802 value and repeats the process.

*Ideally for a return of true or false, the function return type should be Boolean, but for some good reason, i was getting error using same, so return type String was used.

Type 2 code working

Function is defined with two parameters, one input and one output, and return type void.

def void ExistsAndHasValue(String[] Input, Output output)

Further, unlike previous type code, this takes one complete context values as an input at a time i.e. 1st time input will be 20210801 & 20210802 of first context, 2nd time input will be 20210801, empty value & 20210803 of second context into an array Input.

Next, for loop iterates for every element of the Input array, by checking for the size of the array. In first case array size is 2, in second case array size is 3.

Further, it checks if it is null or empty value. Based on the the condition, the result string “true” or “false” is added to output object, and adds on to the output array, and returns the output for context. Next repeats with the next context values.

Points to be noted here is,

  1. Both the parameters here are of object type. Input is an array object of type string, and output is an object of class Output.
  2. to use Output class, it is required to use all the parameters as an object only, and cannot be single variable type.
  3. When Output class is being used, the return type of the function should be ‘void’ only, else you will face issue like ‘No valid return type’
  4. while using Output class, output is obtained using output.addValue(value_to_be_returned)
  5. Output class is of great significance, and enables us to play around with the ouput to be obtained, as type 1 coding not always will fulfil our requirement of context handling.

Example 2

Type 1 Coding

//Qualifiers need to be separated by semi-colon (;)
import com.sap.it.api.mapping.*;

def String ExistsAndHasOneOfSuchValue(String Input, String Qualifier)
{
	if (Input != null && Input.trim().length()>0 && Qualifier!=null && Qualifier.trim().length()>0) //check if Input has a value
	{
		String[] str = Qualifier.split(';') 
		int count=0
		for( String values : str )
		{
		  if (Input==values)
		  {
			count++
		  }
		}
		if(count>0)
		{
			return true
		}
		else
		{
			return false
		}
	}
	else
	{
		return false
	}
}

Type 2 Coding

//Qualifiers need to be separated by semi-colon (;)
import com.sap.it.api.mapping.*;

def void ExistsAndHasOneOfSuchValue(String[] Input, String[] Qualifier, Output output)
{
	for (int i=0; i<Input.size();i++)
	{
    	if (Input[i] != null && Input[i].trim().length() > 0 && !output.isSuppress(Input[i]))
    	{
    	    if(Qualifier[0] != null && Qualifier[0].trim().length() > 0)
    	    {
        	    String[] str = Qualifier[0].split(';')
        	    int count=0

        	    for (String value : str)
        	    {
        	        if(Input[i]==value)
        	        {
        	            count++
        	        }
        	    }
        	    if(count>0)
        	    {
        	        output.addValue(true) //return true to output if input value matches given qualifiers
        	    }
        	    else
        	    {
        	        output.addValue(false) //return false if input value doesn't match given qualifiers
        	    }
    	    }
    	    else
    	    {
    	        output.addValue(false) //return false if no qualifier is available
    	    }
    	}
    	else
    	{
    	    output.addValue(false) //return false if no input is available
    	}
	}
}

 

Sample Input & Output

Code Working

Here, unlike previous example, two inputs are taken, both of type string. In first type, function has a return type, whereas in 2nd type, output object is used. The function takes two inputs, checks if both exists and has a non-empty value. Then, it splits the second input string i.e. qualifiers here, as per the given delimiter and stores in an array of string. then runs a loop and compares 1st input with second input to decide if anything matches, if it matches it increments a variable called count, else the value of count remains 0 (zero), and then based on value of count variable, it returns true or false to the output.

Since, second input i.e. Qualifier will be given by a constant and will not have any queue, hence the parameter is though taken as object but is used as single variable by giving index as 0 i.e. Qualifier[0].

The major part to focus here is !output.isSuppress(Input[i]). If a SUPPRESS is provided to type 1 code, the code gives an error, as there is no way that we can make code understand what is a suppress input. But with the help of Output class in-built function isSuppress(), this functionality is achieved. Hence, this deflects our point of focus towards type 2 coding pattern, as handling context, handling null and SUPPRESS is of utmost importance in integration process.

Further more, the above example had 1:1 relation between input and output, i.e for every input, some output was given, but with the examples of functions such as ContexthasOneOfSuchValue, getValueByIndex, where we do not need 1:1 output , but a conclusive output from one single context queue, we will be able to prove why type 2 coding pattern is important, and how it is made possible with it.

Conclusion

We have been able to justify what makes type 2 coding pattern more important than type 1 coding. Hence, here after in further scripts, type 2 coding pattern will be followed for demonstration purpose.

Be the first to leave a comment
You must be Logged on to comment or reply to a post.