Ariba Cloud Integration, Cloud Integration

Integrate Ariba ITK Services with CPI

Requirement:

Integrate SAP Ariba ITK services with SAP CPI.

Overview

SAP Ariba ITK (Integration Tool Kit) helps to integrate SAP Ariba with any ERP system to exchange master and transactional data via coma-separated-value (CSV) file upload and download. Refer SAP Ariba integration toolkit guide SAP Ariba integration toolkit guide for more details. To integrate SAP Ariba ITK with SAP PO, SAP Ariba Integration Toolkit is installed on SAP PO. SAP Ariba Procurement Solution will generate the data in a CSV file and place it the desired SAP PO SFTP folder location. But in SAP CPI there is no such provision to install integration toolkit. To achieve this SAP Ariba is exposed as a Ariba ITK Style service and SAP CPI sends file upload and download request in MIME multipart format.

In this blog post I will share how to download and upload files to SAP Ariba ITK Services from SAP CPI in 2 sections. More details are provided in the solution section below.

Solution:

The approach to integrate SAP ARIBA will be divided into 2 sections:

  1. File download
  2. File Upload

Section1: File download: Integration Process Details:

Download csv data file from Ariba Style ITK service to SFTP location.

Figure 1: File Download iFlow

Get Ariba MIME Parameters: Set the Ariba MIME parameters in content modifier

Figure 2:Get Ariba MIME Parameters for file download

MIME Ariba Request:

Groovy script for MIME request to download files from SAP Ariba ITK style service.

Below parameters need to be passed in MIME request:
sharedsecret: Ariba credentials

event: Event required to pull data from Ariba.

clienttype, clientinfo, clientversion: Source system details (SAP CPI system details in this case)

from and to: Date range to pull data. In above case I have selected date range from 20th Dec 2022 to current date time.

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import java.util.Iterator;
import javax.activation.DataHandler;
import javax.mail.internet.ContentType;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import com.sap.it.api.ITApi
import com.sap.it.api.ITApiFactory
import com.sap.it.api.securestore.*
import com.sap.gateway.ip.core.customdev.util.Message

def Message processData(Message message) {
   
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
    
    def SharedSecret = message.getProperties().get("SharedSecret")
	def Event = message.getProperties().get("Event")
    def ClientType = message.getProperties().get("ClientType")
    def ClientInfo = message.getProperties().get("ClientInfo")
    def ClientVersion = message.getProperties().get("ClientVersion")
    def From = message.getProperties().get("FromDate")
    
    //Get current system date and time
    def date = new Date()
    def dtFormat = "E MMM dd HH:mm:ss z YYYY"
    def CurrentDate = date.format(dtFormat, TimeZone.getTimeZone('CET'))
    def To = CurrentDate
    message.setHeader("CurrentDate", CurrentDate);
    
    try{
    
        byte[] bytes = message.getBody(byte[])
		 //  Construct Multipart
        MimeBodyPart bodyPartHead1 = new MimeBodyPart()
        bodyPartHead1.setText(SharedSecret)
        bodyPartHead1.setDisposition('form-data; name="sharedsecret"')
        
        MimeBodyPart bodyPartHead2 = new MimeBodyPart()
        bodyPartHead2.setText(Event)
        bodyPartHead2.setDisposition('form-data; name="event"')
        
        MimeBodyPart bodyPartHead3 = new MimeBodyPart()
        bodyPartHead3.setText('ClientType')
        bodyPartHead3.setDisposition('form-data; name="clienttype"')
        
        MimeBodyPart bodyPartHead4 = new MimeBodyPart()
        bodyPartHead4.setText(ClientInfo)
        bodyPartHead4.setDisposition('form-data; name="clientinfo"')
        
        MimeBodyPart bodyPartHead5 = new MimeBodyPart()
        bodyPartHead5.setText(ClientVersion)
        bodyPartHead5.setDisposition('form-data; name="clientversion"')
        
        MimeBodyPart bodyPartHead6 = new MimeBodyPart()
        bodyPartHead6.setText(From)
        bodyPartHead6.setDisposition('form-data; name="from"')
        
        MimeBodyPart bodyPartHead7 = new MimeBodyPart()
        bodyPartHead7.setText(To)
        bodyPartHead7.setDisposition('form-data; name="to"')
               

        MimeMultipart multipart = new MimeMultipart()
        multipart.addBodyPart(bodyPartHead1)
        multipart.addBodyPart(bodyPartHead2)
        multipart.addBodyPart(bodyPartHead3)
        multipart.addBodyPart(bodyPartHead4)
        multipart.addBodyPart(bodyPartHead5)
        multipart.addBodyPart(bodyPartHead6)
        multipart.addBodyPart(bodyPartHead7)
        

        multipart.updateHeaders()
        
        multipart.writeTo(outputStream)
        message.setBody(outputStream)
    
        // Set Content type with boundary
        String boundary = (new ContentType(multipart.contentType)).getParameter('boundary');
        message.setHeader('Content-Type', "multipart/form-data; boundary=\"${boundary}\"")
        
        // Calculate message size
        message.setHeader('content-length', message.getBodySize())
    
    }catch(Exception e){
        
    }finally{
        outputStream.close()
    }


    return message
}

Ariba_HTTPS_RequestReply: Ariba connection configurations

Figure 3: Ariba HTTPs Request

Section 2: File upload: Integration Process Details:

Upload csv data file from CPI to Ariba Style ITK service.

Figure 4: File Upload iFlow

Input CSV Payload:

Figure 5: Input CSV Data

Get Ariba MIME Parameters: Set the Ariba MIME parameters in content modifier

Figure 6: Get Ariba MIME Parameters for file upload

Zipped CSV File: Groovy script to create a zipped csv file:

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import java.io.IOException;
import java.util.Arrays;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.apache.camel.impl.DefaultAttachment;
import javax.mail.util.ByteArrayDataSource;

def Message processData(Message message) {
	//Read the filename and attachment name
	def FileName = message.getProperties().get("FileName");
	def Attachment = message.getProperties().get("Attachment");
	
   //Body
    def body = message.getBody(java.lang.String) as String; // this value is used for the CSV file
    byte[] b = body.getBytes(); // converting body to byteArray
    ByteArrayOutputStream byteArrayOutputStreamcsv = new ByteArrayOutputStream();
    byteArrayOutputStreamcsv.write(b,0,b.length);

    // Zipping Content
    ByteArrayOutputStream zipbyteArrayOutputStream = new ByteArrayOutputStream();
    ZipOutputStream zos = new ZipOutputStream(zipbyteArrayOutputStream);
    
    ZipEntry ze2 = new ZipEntry(FileName); // give csv file name as per naming convention
    
    zos.putNextEntry(ze2);
    byte[] bytescsv =  byteArrayOutputStreamcsv.toByteArray() // putting CSV content in byteArray
    zos.write(bytescsv, 0, bytescsv.length);
    zos.closeEntry();
    zos.close();
    
   
    def dataSource = new ByteArrayDataSource(zipbyteArrayOutputStream.toByteArray(),'application/zip') //  Construct a DefaultAttachment object
    def attachment = new DefaultAttachment(dataSource) //    Add the attachment to the message
    message.addAttachmentObject(Attachment, attachment) // give zipfile name as per naming convention
    return message;
}

Check Attachment Exists: Groovy script to check if attachment exists

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import java.util.Iterator;
import javax.activation.DataHandler;

def Message processData(Message message) {

   Map<String, DataHandler> attachments = message.getAttachments()
   if (attachments.isEmpty()) {
       message.setBody("No attachment Found")
     return message;
   } else {
      Iterator<DataHandler> it = attachments.values().iterator()
      DataHandler attachment = it.next()
      message.setBody(attachment.getContent())
   }
   return message
}

Setup Ariba MIME parameters: Groovy script for MIME request to download files from SAP Ariba ITK style service.

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import java.util.Iterator;
import javax.activation.DataHandler;
import javax.mail.internet.ContentType;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import com.sap.it.api.ITApi
import com.sap.it.api.ITApiFactory
import com.sap.it.api.securestore.*
import com.sap.gateway.ip.core.customdev.util.Message


def Message processData(Message message) {
    
    //Fetch the parameters
    def SharedSecret = message.getProperties().get("SharedSecret")
    def Event = message.getProperties().get("Event")
    def ClientType = message.getProperties().get("ClientType")
    def ClientInfo = message.getProperties().get("ClientInfo")
    def ClientVersion = message.getProperties().get("ClientVersion")
    def FullLoad = message.getProperties().get("FullLoad")
    def Attachment = message.getProperties().get("Attachment");
        
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
    
    try{

        byte[] bytes = message.getBody(byte[])
        //  Construct Multipart
        MimeBodyPart bodyPartHead1 = new MimeBodyPart()
        bodyPartHead1.setText(SharedSecret)
        bodyPartHead1.setDisposition('form-data; name="sharedsecret"')
        
        MimeBodyPart bodyPartHead2 = new MimeBodyPart()
        bodyPartHead2.setText(Event)
        bodyPartHead2.setDisposition('form-data; name="event"')
        
        MimeBodyPart bodyPartHead3 = new MimeBodyPart()
        bodyPartHead3.setText(ClientType)
        bodyPartHead3.setDisposition('form-data; name="clienttype"')
        
        MimeBodyPart bodyPartHead4 = new MimeBodyPart()
        bodyPartHead4.setText(ClientInfo)
        bodyPartHead4.setDisposition('form-data; name="clientinfo"')
        
        MimeBodyPart bodyPartHead5 = new MimeBodyPart()
        bodyPartHead5.setText(ClientVersion)
        bodyPartHead5.setDisposition('form-data; name="clientversion"')
        
        MimeBodyPart bodyPartHead6 = new MimeBodyPart()
        bodyPartHead6.setText(FullLoad)
        bodyPartHead6.setDisposition('form-data; name="fullload"')
        
        MimeBodyPart bodyPart = new MimeBodyPart()
        ByteArrayDataSource dataSource = new ByteArrayDataSource(bytes, 'application/zip')
        DataHandler byteDataHandler = new DataHandler(dataSource)
        bodyPart.setDataHandler(byteDataHandler)
        bodyPart.setFileName(Attachment)
        bodyPart.setDisposition('form-data; name="content"')
    
        MimeMultipart multipart = new MimeMultipart()
        multipart.addBodyPart(bodyPartHead1)
        multipart.addBodyPart(bodyPartHead2)
        multipart.addBodyPart(bodyPartHead3)
        multipart.addBodyPart(bodyPartHead4)
        multipart.addBodyPart(bodyPartHead5)
        multipart.addBodyPart(bodyPartHead6)

        
        multipart.addBodyPart(bodyPart)
        
        multipart.updateHeaders()
        
        multipart.writeTo(outputStream)
        message.setBody(outputStream.toByteArray()); 
        // Set Content type with boundary
        String boundary = (new ContentType(multipart.contentType)).getParameter('boundary');
        message.setHeader('Content-Type', "multipart/form-data; boundary=\"${boundary}\"")
        

    }catch(Exception e){
        
    }finally{
        outputStream.close()
    }


    return message
}

Ariba_HTTPS_RequestReply: Ariba Connection Configurations

Figure 7: Ariba HTTPs Request

Testing:

Test Case1: File download

MIME request sent to SAP Ariba

Figure 8: MIME request sent to SAP Ariba

Zip file generated in SFTP directory:

Figure 9: Output Zip file

Test Case2: File upload

MIME request sent to SAP Ariba

Figure 10: MIME request sent to SAP Ariba

Ariba Response:

Figure 11: Ariba Response