Skip to Content

Suppose business requirement is like:

  • Read multiple CSV files in to single Zip File and send it as an attachment to third Party

Then for such business requirement one sap-pi scenario can be created like:

  • Soap to File Inbound Synchronous Interface
  • that means one sap-pi soap web-service synchronous scenario where:
    1. in Response Message Mapping, one UDF will be required to Read files and set them as an zip attachment
    2. Scenario will have Communication Channels like Soap Sender and File Receiver
    3. File Receiver channel’s job will be only to create a dummy empty file in SAP’s app directory and that file will be overwritten for each time. This File channel is required only to complete scenario.

SAP PI UDF example which is “To Set multiple CSV file as an zip Attachment to Response Message Payload”, will have below functionality :

  • To read multiple CSV files from folder
  • compress them to a single Zip file. Here limit 10 CSV files per zip
  • Archive each zipped CSV file to other directory
  • Set zip file as an attachment
  • Set Zip File name to Dynamic Configuration variable, so that same FileName can be used further

//=======================================================================

public String zipToAttachment(String filePath, String archivePath, Container container) 
throws StreamTransformationException{

/*
UDF for below functionalities:
To get current Date time
To Read 10 files from a directory of SAP-APP server (only .CSV files and should not starts with "ARC")
To zip 10 files in a single zip file and rename zip as "zipFileName_currentDateTime"
To archive 10 files to other directory
To set single zip file as attachment to HTTP response message
To set attachment header as "application/zip"
*/

//Start of :Get Current Date Time ............................................
//Current DateTime to be used in ZipFileNaming conventions
DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd : HHmmssSSS");
Date date = new Date();
String cDate = dateFormat.format(date).toString();
cDate = cDate.replaceAll(" : ", "T");
//End of : Get Current Date Time .............................................

String Input_filePath   = filePath;
String Archive_filePath = archivePath;
String Ouput_Zip = "zipFileName_" + cDate + ".zip";//zipFileName_20170610T112255987.zip
String resultStr = "";
Boolean csvFound = false;
String errorStr  = "";


//Start of CsvFile Zipping and archinving to other folder ....................
try{
File[] fileDir = new File(Input_filePath).listFiles();
if (fileDir.length > 0) {
FileOutputStream fos = new FileOutputStream(Ouput_Zip);
ZipOutputStream zos = new ZipOutputStream(fos);

int fileCount = 0;

//Read each file in th directory
for (int i=0; i<fileDir.length; i++){

String Input_fileName = fileDir[i].getName();       //Get FileName
String Input_fileName_Path = fileDir[i].getPath();  //Get FileName with PathName


//Each file should be ".CSV" and should not startswith "ARC"
if(Input_fileName.startsWith("ARC")) {
        //do nothing
}else{  // if fileName is not starting with "ARC"
if (Input_fileName.lastIndexOf(".CSV")  > -1){
csvFound = true;  //Here CSV file found

//start: Csv file zipping in to single zip ---------------------------
File file = new File(Input_fileName_Path);
FileInputStream fis = new FileInputStream(file);
ZipEntry zipEntry = new ZipEntry(file.getName());
zos.putNextEntry(zipEntry);

byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zos.write(bytes, 0, length);
}
zos.closeEntry();
fis.close();
//End of Csv file zipping in to single zip ---------------------------

//start: File archival -----------------------------------------------
file.renameTo(new File(Archive_filePath + file.getName()));
//end:  File archival ------------------------------------------------

//Read only 10 CSV files for one Zip
fileCount = fileCount + 1;
if (fileCount == 10){
    break;   //break the (for...loop) if fileCount reached 10
}// end of    "if case for fileCount"

}// end of "if case for CSV file Check"
} // end of "else if case for ARC file Check"
}//end of "for loop case for FileDirectiry"

if(csvFound == false){
  errorStr += " | " + "No .CSV file found in directory: " + Input_filePath ;
}else{
  //if atleast one .CSV file found with "ARC" prefix, only then zip file gets created
  //and only then it is requried to close ZipOutputStream 'zos' and FileOutputStream 'fos'
  zos.close();
  fos.close();

//start: set zip as an Attachment ------------------------------------
//Return Zip file as an attachment to Soap Response Message
InputStream zipIpStrm =  new FileInputStream(Ouput_Zip);
byte[] buffer = new byte[0xFFFF];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (int len; (len = zipIpStrm.read(buffer)) != -1;){
baos.write(buffer, 0, len);
baos.flush();
}

GlobalContainer gblCtnr = container.getGlobalContainer();
OutputAttachments opAtch = gblCtnr.getOutputAttachments();
Attachment Atch = opAtch.create(Ouput_Zip, "application/zip", baos.toByteArray());
opAtch.setAttachment(Atch);
//end:  set zip as an Attachment -----------------------------------------

                                }

}//end of "if (fileDir.length > 0) {"
}catch(Exception e){
  errorStr += " | " + e.getMessage();
}
//End of CsvFile Zipping and archinving to other folder ...................



if (errorStr == ""){
  resultStr  = Ouput_Zip; //set zipFileName to return string
}else{
  resultStr  = errorStr;         //return error
}
return resultStr;

}//end of UDF Fn "zipToAttachment"

 

//=======================================================================

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply