Skip to Content
Product Information

Enterprise Integration with SAP CPI (Part 2 of 4)

Hello technology hitchhikers!

Welcome to the second part of Enterprise Integration with SAP CPI. In the first part (read here if you haven’t) we had established our integration scenario, divided the approach into 7 steps and also discussed the first two steps of the solution.

  1. Configure the Integration to run every day
  2. Obtain the list of products
  3. For each product in the list, identify if reordering is required
  4. If product must be reordered, obtain supplier info
  5. Create a list of the products to be reordered along with supplier info
  6. Convert List into csv format
  7. Send List to Manager via Email

And we got to learn about Start Timer and Request Reply shapes as we used them in our integration flow.

At this stage, we have the list of products for which an order hasn’t been placed already. We need to look into the units in stock and reorder level for the products to assess if they need to be reordered. Instead of trying to process the entire product list in one go, we are going to divide the list into individual products and then do the assessment one product at a time.

This step can be further broken down into 2 parts:

  1. Pick a single product from the list of products obtained
  2. Identify if that product requires reordering

Pick a single product from the list of products obtained

(Technical concepts used: Splitter)

To split the list into individual products for assessment, we use a splitter.

Splitter is a group of shapes which are used to split a composite message into individual messages. There are various kinds of splitter available in SAP CPI, like Iterating Splitter, General Splitter, EDI Splitter etc. The ones used most often are General and Iterating splitter, both of which serve the purpose of splitting a general document into it’s constituent elements. The difference between the two is that general splitter includes the enclosing tags in the individual messages whereas Iterating splitter does not. To illustrate this difference, let us take an example.

Suppose the list of products is maintained as:

<Products>
    <Product>
        <Id>1</Id>
        <Name>Biscuit</Name>
    </Product>
    <Product>
        <Id>2</Id>
        <Name>Tea</Name>
    </Product>
    <Product>
        <Id>3</Id>
        <Name>Coffee</Name>
    </Product>
</Products>

We can split this list into individual products using either General or Iterative Splitter. Let us look at the output obtained from both of them to understand the difference in a more clear manner.

On using a General splitter and splitting on Product, we get the individual product as:

<Products>
    <Product>
        <Id>1</Id>
        <Name>Biscuit</Name>
    </Product>
</Products>

As you can see, the enclosing <Products> tag is present even after splitting.

When we use an iterative splitter and split on Product, we obtain the following result. Note that the enclosing <Products> tag is missing here.

<Product>
    <Id>1</Id>
    <Name>Biscuit</Name>
</Product>

In a more complex scenario where the nesting of tags runs deeper, the difference will be much more evident, and you will have to decide which splitter you need to use based on whether you want to retain the enclosing tags or not.

Now that we have discussed the basics of splitters, let us look into the configuration of splitter to be used in our scenario.

Click on Routing ->Splitter->General Splitter.

Drop the splitter shape between Request Reply Shape and End Message shape:

We could have used an iterative splitter here as well but our scenario is so simple that it doesn’t make much of a difference. Following is the splitter configuration:

We want to break down the list into individual products and since the list is in XML format, we can use XPath expression to do so and that’s why we have set Expression Type to Xpath. The Product Details are enclosed within <Product> tag and all Products are enclosed within <Products>. Hence the XPath Expression we use is: /Products/Product. Also, we want to deal with details of only one product at a time, hence we set the Grouping parameter to 1. When we enable Streaming, the splitter does not wait for the entire data set to be loaded before it can start splitting. Once the data is split into smaller parts, these parts are processed in a sequential manner. If there is no correlation between these parts, we can enable Parallel Processing. For our scenario, we enable parallel processing since data of each product is independently analysed to check if reordering is needed. We keep the Number of Concurrent Processes and Timeout parameters set to the default value. It might happen that one of these parts encounters an exception. By enabling Stop on Exception, we make sure that we do not process the rest of the parts.

Now that we have configured the splitter, the list of products obtained in the previous steps will be split into individual products. The next step is to assess whether the product needs to be reordered. For this purpose, we are going to use a groovy script.

Identify if that product requires reordering

(Technical concepts used: Groovy Script)

Scripting is one of the most powerful features provided by SAP CPI. When none of the existing shapes can be configured to process data as per our requirement, we can develop a script that implements our logic.

In our scenario, we are going to use Groovy Script to assess if a product requires to be reordered. To add a Groovy script to your integration flow, click on Message Transformers->Script->Groovy Script

Drop the shape between General Splitter and the end message shape.

At this point, we have inserted the shape in our integration flow, but there is no script added to the Groovy Script shape. For Adding a script, click on the shape, and then on the + symbol on its right.

When you click on the + button, a new script is added to the shape:

As you can see, this script contains a method by the name ‘processData’ which takes incoming Message as an argument and returns the Message after processing. Also the method is divided into 3 sections: Body, Headers and Properties. Every message in the integration flow has a bodymessage headers and message exchange properties, among other things. The message body contains the payload. In our scenario, it contains the product data that we obtained using Request Reply shape in a previous step.

Message Headers usually contain metadata and along with Message Exchange Properties, it can be used for storing data that is not part of the body but is required for processing. For example, after assessment of product details, we can store a parameter in Headers/Properties which indicates if reordering is required.

The difference between data stored in header and property is that of scope. Data is stored in property only till the message is in the middleware and is not passed on to the receiver whereas data stored in Header is passed on to the receiver.

Following is the script that we are going to use:

import com.sap.gateway.ip.core.customdev.util.Message;
import groovy.util.XmlSlurper ;
import java.util.HashMap;
import groovy.xml.XmlUtil;

def Message processData(Message message) {
       def body = message.getBody(java.lang.String) as String;
       def reorderLevel;
       def unitsInStock;
       def product= new XmlSlurper().parseText(body);
       reorderLevel=product.Product.ReorderLevel.text().toInteger();
       unitsInStock=product.Product.UnitsInStock.text().toInteger();
       if(unitsInStock<=reorderLevel){
          message.setProperty("needsReorder", "true");
       }
       else{
           message.setProperty("needsReorder", "false");
       }
       return message;
}

In this Script, we first obtain the message body containing Product Details as String. Note that the Script shape has been placed after the Splitter, hence, the message body will contain Details of a single product at one go and several such segments will be processed in parallel.

We convert the string body into XML Node using XML Slurper. XML Slurper converts the string into a document tree that may be traversed similar to XPath expressions.

We obtain the Reorder Level and Units is Stock of the products and compare them. If the Units in Stock is less than or equal to the Reorder level, which acts as a threshold here, we set a message exchange property needsReorder to true. Otherwise, we set it to false. Thus, using this script, we are able to determine if a product needs to be reordered or not.

Soft, no haste! -Portia, The merchant of Venice

Remembering the virtue of proceeding slowly and steadily, we are going to take a pause here. In this blog post, we learned about Splitters and also about the differences in General and Iterative Splitter. We also learned about Groovy Script, Message Headers and Exchange Properties while developing our integration flow. In the next blog post, we will continue our journey of Enterprise Integration using SAP CPI. Till then, goodbye and happy learning!

This was originally posted on Integrtr Blogs.

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