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:
- File download
- File Upload
Section1: File download: Integration Process Details:
Download csv data file from Ariba Style ITK service to SFTP location.
Get Ariba MIME Parameters: Set the Ariba MIME parameters in content modifier
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
Section 2: File upload: Integration Process Details:
Upload csv data file from CPI to Ariba Style ITK service.
Input CSV Payload:
Get Ariba MIME Parameters: Set the Ariba MIME parameters in content modifier
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
Testing:
Test Case1: File download
MIME request sent to SAP Ariba
Zip file generated in SFTP directory:
Test Case2: File upload
MIME request sent to SAP Ariba
Ariba Response: