Suppress Multiple Header Lines When Appending the File With Multiple Messages
Introduction
When you create one file using append mode option in receiver file adapter with multiple messages which contains header and line items, the requirement is to create only one header instead of multiple headers in single file as mentioned in this discussion How to ignore the header record in every line i… | SCN
There is no standard way to handle this requirement, the possible solutions are
- Run operating system command after message processing
- Write a UDF which read the file using FTP classes and check for the file existence
Both approaches are not recommended for some specific reasons.
- For operating system command: The message will not fail if operating system command failed to execute.
Defining Operating System Commands Before/After Processing – Advanced Adapter Engine – SAP Library
Message processing is independent of any errors that occur during the execution of a configured operating system command.
- SAP is not recommended to use FTP logic in the message mapping.
In this blog i want to show one of the possible solution using static map in message mapping.
Structures and Mapping
Create source and target structure like below and do the one to one mapping except Header node.
Create the variable called fileName and map the dynamic file name using UDF which i explained in other blog Reuse FunctionLibrary for DynamicConfiguration and Message Header Attributes
Also pass the file name to the UDF called isOrderFileExist , if the file not exist in the static map then i am creating the header node which means first message, from second message on wards the file name will be exist in the static map and header node will not be created.
isOrderFileExist UDF:
@LibraryMethod(
title="isOrderFileExist",
description="",
category="User-Defined",
type=ExecutionType.SINGLE_VALUE)
public String isOrderFileExist (
@Argument(title="") String fileName,
Container container) throws StreamTransformationException{
currentDate = sdf.format(new Date());
List<String> orderFileList = getOrderMap().get(currentDate);
if (orderFileList == null) {
orderFileList = new ArrayList<String>();
getOrderMap().put(currentDate, orderFileList);
}
if (orderFileList.contains(fileName))
return "true";
else {
orderFileList.add(fileName);
return "false";
}
}
The below are static map which holds the file names for each day and required variables and also getOrderMap to get the order file map.
private static Map<String, List<String>> orderMap = new HashMap<String, List<String>>();
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
private String currentDate;
public static Map<String, List<String>> getOrderMap() {
return orderMap;
}
The cleanup method will remove the file names which older than one day from the map.
@Cleanup
public void cleanup (
GlobalContainer container) throws StreamTransformationException{
for (Map.Entry<String, List<String>> orderFileMap : getOrderMap().entrySet()) {
try {
if (sdf.parse(currentDate).after(sdf.parse(orderFileMap.getKey())))
getOrderMap().remove(orderFileMap.getKey());
} catch (ParseException e) {
throw new StreamTransformationException(e.getMessage());
}
}
}
IFLOW
Create IFLOW like below, i used SOAP sender and receiver file adapter to append the file.
File Adapter Configuration
Testing
I sent below message from SOAP UI.
The below file created in the target directory.
And the file contents:
Send the second message with different line number with same order number.
File updated with the line number which we sent above without header line.
Conclusion
This is just one of the way to achieve this requirement, we need to tweak this based on the requirement, if you want to resend the message you cannot resend because the file name will be already in the map and will not create the header in the file but you can resend next day based on above logic but it depends on the requirement, this just to give you an example. Hope it helps!
Nice one Praveen , Much Needed! 🙂
If the system is restarted on the same day(doesn't happen but curious to know) does the static Map holds the list before the system restart ? If the static map doesn't hold value after system restart then i guess it will add new header to the message triggered after restart ?
Usually i use Seeburger Mapping variable for the same requirement 😛
Br,
Manoj
Hi Praveen,
Does this UDF works only End to end ?
Because i passed a constant value to the UDF and it returned false , and again i passed the same value still it is returning false ? Am i doing anything wrong ? I tested this locally in ESR.
Thanks in Advance,
Kiran
Hi Praveen!
Thanks for sharing this!
And what happens if third party application takes target file for processing with variuos time intervals within one day? I just consider the situation when we need dynamic file existance checking.
Regards, Evgeniy.
Nice one Praveen
We need one clarification  about static map code where need to be placed in Mapping.
Note : we are using SWING client In stand  of  NWDS .
Regards
Srikanth