SAP Cloud Platform Integration (CPI) Part 16 – Common Groovy Script codes

In this post, we will explore a few common Groovy Script codes that are frequently used and can add cool functionality to your project.

Outline of this blog series: Common Groovy Script codes

1. SAP CPI Introduction
2. SAP BTP tools and features overview (BTP, Global Account, Sub-Account, Entitlements, Connectivity, Security)
3. SAP CPI Web IDE overview
4. Registering a trial account and enrolling to SAP CPI service
5. Deep dive into Cloud Integration features with real world scenario example
6. Use cases of palette functions
7. Adapter configurations
8. Using Cloud connector for connecting to backend SAP systems
9. Overview on API Management & Open Connectors
10. Integration using Open Connectors with real world example

In short, below is the content we will elaborate in this tutorial:

1. Logging the payload
2. Get Property value
3. Check for Alphanumeric value
4. Dynamic Receiver Determination
5. URL Encoding
6. Convert String to Integer/Boolean value
7. Handling HTTP Batch Response errors


Groovy scripting is an essential and important aspect of SAP Cloud Platform Integration (CPI). Here are some common Groovy script codes frequently used in SAP CPI to enhance functionality and streamline processes.

  • Information change: Cool contents are frequently used to change information starting with one configuration then onto the next, for example, switching XML over completely to JSON or the other way around.
  • Dynamic directing: Sweet scripts can be utilized to decide the objective of a message powerfully founded on its substance or different measures.
  • Payload control: Cool contents can be utilized to change the substance of a message, for example, adding or eliminating components, refreshing qualities, or sifting information.
  • Blunder dealing with: Awesome contents can be utilized to deal with mistakes and exemptions that happen during message handling, like logging mistakes or sending notices.
  • Custom handling: Cool contents can be utilized to execute custom handling rationale that isn’t accessible out of the container in CPI, like custom encryption or unscrambling.
  • Document taking care of: Awesome contents can be utilized to interface with records, like perusing or composing records, renaming, or erasing records, or moving documents to various areas.
  • Date and time control: Cool contents can be utilized to perform procedure on date and time values, for example, parsing date strings, designing dates, or working out time contrasts.
  • Peaceful web administration mix: Sweet scripts can be utilized to coordinate with outer Tranquil web administrations, for example, sending HTTP demands, taking care of reactions, or parsing JSON or XML information.

We will begin from the fundamental scripts and go for complex situations:

Logging the Payload

import com.sap.gateway.ip.core.customdev.util.Message;import java.util.HashMap;

def Message logInput(Message message)
{   
    def body = message.getBody(java.lang.String) as String;
    def messageLog = messageLogFactory.getMessageLog(message);
         if(messageLog != null)
           {
        messageLog.setStringProperty("log2","Printing Payload As Attachment")
        messageLog.addAttachmentAsString("IDOCPayload",body,"text/plain");
	}
  return message;
}

This Cool content characterizes a capability called logInput which takes in a solitary contention message of type com.sap.gateway.ip.core.customdev.util.Message.

The capability initially recovers the body of the information message and converts it to a String utilizing the getBody technique given by the Message class. It then, at that point, makes a message log utilizing the getMessageLog technique for the messageLogFactory object. In the event that the message log object isn’t invalid, it sets a custom string property called “log2” on the message log object to “Printing Payload As Connection”. It then, at that point, adds the payload of the information message as a connection to the message log object with a name “IDOCPayload” and content sort “message/plain”.

At last, the capability returns the first info message object.In rundown, the reason for this content is to log the payload of an information message as a connection with a custom message log object, which can be helpful for troubleshooting and following purposes in a mix situation.

Get Property Value

import com.sap.it.api.mapping.MappingContext
def String getProperty(String propertyName, MappingContext context)
{    def propertyValue = context.getProperty(propertyName);    
        return propertyValue;
}

This Sweet content characterizes a capability called getProperty which takes in two contentions: propertyName of type String and setting of type com.sap.it.api.mapping.MappingContext. The capability initially recovers the worth of the predetermined property utilizing the getProperty strategy given by the MappingContext object and doles out it to a nearby factor called propertyValue. It then returns the propertyValue as a String.

In synopsis, the reason for this content is to recover the worth of a predetermined property from a MappingContext object, which can be valuable in different planning and mix situations.

Check for Alphanumeric Value

import com.sap.it.api.mapping.*;
def String customFunc(String arg1){
 for (int i = 0; i < arg1.length(); i++) 
   {
       if(Character.isDigit(arg1.charAt(i)))
       return "false";
    }
  return "true";
 }

This Cool content characterizes a capability called customFunc which takes in a solitary contention arg1 of type String. The capability utilizes a for circle to repeat through each person in the info arg1 String. For each person, it checks whether it is a digit utilizing the isDigit technique given by the Person class. Assuming it finds a digit in the information String, the capability promptly returns the string “bogus”, demonstrating that the information string contains no less than one digit. Assuming it finishes the circle without finding any digits, it returns the string “valid”, showing that the info string contains no digits.

In outline, the reason for this content is to check whether a given info string contains any digits, which can be valuable for information approval and change in different mix situations.

Dynamic Receiver Determination

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap
import com.sap.it.api.ITApiFactory
import com.sap.it.api.mapping.ValueMappingApi
import groovy.json.*
  def Message processData(Message message) {
    try {
      // Read the routing condition from the property
      def value = message.getProperty("TestEnv")
      // Identify the Receiver based on the routing condition 
      if (value) {
        if (value.equals('FUT')) {
          Receiver = "S4_010"
        } else if (value.equals('UAT')) {
          Receiver = "S4_020"
        } else {
          throw new Exception("Receiver could not be identified") //Throw exception if Receiver not mapped for the value
        }
      } else {
        throw new Exception("Routing Condition not Found") //Throw exception if routing condition could not be read
     }
      if (Receiver != null) {
        //Define the parameters required for this interface; Url, Client, User for each API/Service used 

        def p_Url = Receiver + "_Url"
        def p_User = Receiver + "_User"
        def p_Client = Receiver + "_Client"
        //Call the Value Mapping API and pass the paramters
        def valueMapApi = ITApiFactory.getApi(ValueMappingApi.class, null)
        // Fetch the values for connection parameters 
        def RCV_Url = valueMapApi.getMappedValue('Receiver', 'Parameter', p_Url, 'Receiver', 'Value')
        def RCV_Client = valueMapApi.getMappedValue('Receiver', 'Parameter', p_Client, 'Receiver', 'Value')
        def RCV_User = valueMapApi.getMappedValue('Receiver', 'Parameter', p_User, 'Receiver', 'Value')

        if (RCV_Url != null || RCV_Client != null || RCV_User != null) {
          message.setProperties(["Receiver": Receiver,
            "RCV_Url": RCV_Url,
            "RCV_Client": RCV_Client,
            "RCV_User": RCV_User
          ])
        } else {
          throw new Exception("Missing parameters in lookup") //Throw exception if parameters could not be retrieved from VM table
        }
      }
    } catch (Exception ex) {
      throw new Exception(ex)
    }
    return message
  }

URL Encoding

URL encoding is the most common way of changing over information or text into a configuration that can be securely communicated in a URL or Uniform Asset Finder. URLs are utilized to find assets on the web, and they are made out of ASCII characters that are restricted to a particular arrangement of characters. Thusly, in the event that a URL contains characters beyond this set, it might cause blunders or confusion when sent or deciphered by programs, servers, or different applications.

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import java.net.URLEncoder;

def Message processData(Message message) {
    // get properties
   def map = message.getProperties();
   //get validityenddate value
   def value = map.get("ECCConditionValidityEndDate");
//conversion
   def encodedURL = URLEncoder.encode(value, "UTF-8");
//Set Properties 
message.setProperty("ECCConditionValidityEndDate_encoded", encodedURL);
//return the converted value
return message;
}

Convert String to Integer/Boolean value

This utilization cases will generally prove to be useful when you use XML to JSON transformation where all values will get changed over completely to string and the collector probably won’t acknowledge for all intents and purposes. So transformation of string type to whole number or Boolean must be finished through cool contents.

In the event that values are under one parent hub:

import com.sap.gateway.ip.core.customdev.util.Message;
import groovy.json.*
def Message processData(Message message)
{
def body = message.getBody(java.lang.String) as String;
def map  = message.getProperties();
def jsonSlurper = new JsonSlurper();
def jsonDataObject = jsonSlurper.parseText(body);
jsonDataObject.FixedQuantity = convertToBoolean(jsonDataObject.FixedQuantity);
message.setBody(new JsonBuilder(jsonDataObject).toPrettyString())
return message
}

//Integer conversion  
   static Object convertToInt(Object inputValue){
        if(inputValue.isNumber()){
          return inputValue.toInteger();
        }else{
          return inputValue;
        }
   }

//Boolean Conversion
static Object convertToBoolean(Object inputValue){
        if(inputValue.equals("true")){
          return true;
        }else{
          return false;
        }
}

If the value to be converted is under array:

import com.sap.gateway.ip.core.customdev.util.Message
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
def Message processData(Message message) {
    def body = message.getBody(java.lang.String) as String
    def json = new JsonSlurper().parseText(body)
   def positions = json.positions
    positions.each { position ->
        position.selected = Boolean.parseBoolean(position.selected)
        position.quantity = position.quantity.toInteger()
        if (position.durationInDays!='') {
            position.durationInDays = position.durationInDays.toInteger()
        }
       }
   message.setBody(JsonOutput.toJson(json))
    return message
}

Handling the HTTP Batch Response errors

This would prove to be useful when you are utilizing Group handling through HTTP connector. Commonly, in the event that there are different activities to be finished, use of cluster mode will be liked. Yet, in the event that any one activity comes up short and you have different changesets for every activity, the clump activity won’t stop, as you have individual changeset for every activity and the collector/shipper probably won’t have the foggiest idea about the justification for missing qualities in the objective. IFlow will likewise be in Finished status. To catch the blunder and make the IFlow status as Fizzled, underneath content can be utilized.

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import com.sap.it.api.mapping.*;
def Message processData(Message message)
{   
    def body = message.getBody(java.lang.String) as String;
    def messageLog = messageLogFactory.getMessageLog(message)
    if(messageLog != null)
	{
        messageLog.setStringProperty("IncomingPayload","Printing Payload As Attachment")
        messageLog.addAttachmentAsString("HTTP Batch Response",body,"text/plain");
	}
    def reader = message.getBody(java.io.Reader)
    statuscodes = []
    status = []
    reader.eachLine { line ->
           if(line.startsWith("HTTP/1.1 ")) {
def statusCodeStart = line.substring(line.indexOf(" ") + 1)
def statusCode = statusCodeStart.substring(0,statusCodeStart.indexOf(" "))
statuscodes << statusCode
  }
 }
 for(int i=0;i<statuscodes.size;i++){
    if(statuscodes[i].equals('204')){
    status << 'update'
}
   else if(statuscodes[i].equals('201')){
      status << 'create'
 }
    else{
status << 'error'
        }
}
if(status.contains('error')) {
throw new Exception("There is an error in HTTP Batch call. Please check the Batch response")}
message.setProperty("HTTPStatusCodes", statuscodes)
return message
}

This Sweet content cycles a message in the SAP Cloud Stage Combination (CPI) stage. The substance thinks the response from a HTTP bunch call and chooses what is going on with each individual sub-request inside the cluster. The substance at first recuperates the message body as a string and logs it to CPI message log using the message Log Factory object. An substance then, eliminates the response peruser from the message body, which grants it to scrutinize and parse the response data line by line.

The substance purposes a circle to rehash over each line in the response data. It checks whether each line begins with the HTTP/1.1 convention identifier and concentrates the HTTP status code from the line. It then, at that point, stores the status code in an exhibit called statuscodes.

The content then, at that point, emphasizes over every status code in the statuscodes cluster and decides the situation with every individual sub-demand inside the bunch. On the off chance that a status code is equivalent to 204, it adds the string “update” to an exhibit called status. In the event that a status code is equivalent to 201, it adds the string “make” to the status exhibit. On the off chance that the status code is some other worth, it adds the string “mistake” to the status cluster.

The content checks whether the status exhibit contains the string “blunder”. Assuming it does, it tosses an exemption with a message demonstrating that there is a mistake in the HTTP group call. The content sets the HTTPStatusCodes property on the message to the statuscodes exhibit and returns the message.

In summary, this content is used to extract and process the response data from an HTTP batch call in CPI, and to determine the status of each individual sub-request within the batch. It also logs the response data to the CPI message log and checks for errors in the batch response. This approach utilizes common Groovy script codes to handle these tasks efficiently.


Trust the above contents would be valuable for you sooner or later of time. Cheerful learning!

 

YOU MAY LIKE THIS

Future of ABAP on Cloud

Chart of accounts in SAP

Introduction to ABAP on Cloud

X
WhatsApp WhatsApp us