SAP Generic Object Services (GOS) is commonly used to store attachments for business objects such as sales orders, purchase orders, or deliveries.
In SAP PI/PO, many implementations use the RFC function module BDS_BUSINESSDOCUMENT_CREA_TAB to upload binary content to SAP. However, when working with SAP Cloud Integration, handling binary content requires a slightly different approach.
In this blog post, I will demonstrate how to build a simple iFlow that uploads a file from an external system to SAP and stores it as a GOS attachment using the RFC function module BDS_BUSINESSDOCUMENT_CREA_TAB.
Scenario Overview
The scenario works as follows:
- A file is uploaded to an SFTP server.
- Cloud Integration processes the file and converts it into the format required by BDS_BUSINESSDOCUMENT_CREA_TAB.
- The RFC adapter calls the SAP backend system via Cloud Connector.
- The document is stored in SAP and can be accessed via transaction OAOR.
Below is the overall iFlow design.
Processing Steps
Step 1 – Base64 Encode the File
The file content is first Base64 encoded. This prevents issues caused by special characters that may interfere with XML processing in later steps.
Step 2 – Prepare the XML Structure
Next, we prepare an XML message that will be used as the input for message mapping.
Example structure:
<MT_File>
<FileName>${header.CamelFileName}</FileName>
<FileSize>${header.CamelFileLength}</FileSize>
<Content>${body}</Content>
</MT_File>Step 3 – Convert XML into RFC Request
The XML message is then mapped into the RFC structure required by the function module BDS_BUSINESSDOCUMENT_CREA_TAB. Example request:
<?xml version="1.0" encoding="UTF-8"?>
<ns1:BDS_BUSINESSDOCUMENT_CREA_TAB xmlns:ns1="urn:sap-com:document:sap:rfc:functions">
<OBJECT_KEY>0000000001</OBJECT_KEY>
<BINARY_FLAG>X</BINARY_FLAG>
<CLASSNAME>SOFFICEINTEGRATION</CLASSNAME>
<CLASSTYPE>OT</CLASSTYPE>
<COMPONENTS>
<item>
<DOC_COUNT>00000000</DOC_COUNT>
<MIMETYPE>text/plain</MIMETYPE>
<COMP_SIZE>1957</COMP_SIZE>
</item>
</COMPONENTS>
<CONTENT>
<item>
<LINE>446965204DC3BC...E62726F74</LINE>
</item>
<item>
<LINE>656E20756E...CC39FC3A4</LINE>
</item>
</CONTENT>
<SIGNATURE>
<item>
<DOC_COUNT>00000000</DOC_COUNT>
<PROP_NAME>BDS_DOCUMENTCLASS</PROP_NAME>
<PROP_VALUE>TXT</PROP_VALUE>
</item>
<item>
<DOC_COUNT>00000000</DOC_COUNT>
<PROP_NAME>BDS_DOCUMENTTYPE</PROP_NAME>
<PROP_VALUE>TXT</PROP_VALUE>
</item>
<item>
<DOC_COUNT>00000000</DOC_COUNT>
<PROP_NAME>DESCRIPTION</PROP_NAME>
<PROP_VALUE>german_text.txt</PROP_VALUE>
</item>
</SIGNATURE>
</ns1:BDS_BUSINESSDOCUMENT_CREA_TAB>Important Parameters
OBJECT_KEY: The identifier of the business object. For example, for a purchase order it would be like 4500000001, for delivery it would be like 0034423362.
BINARY_FLAG: Set to X because the request contains binary data.
CLASSNAME: Defines the GOS class for the object. For example, `EKKO` would be for pruchase order, `LIKP` would be for delivery.
CLASSTYPE: 'BO' for business object, 'OT' for others
COMPONENTS/item/MIMETYPE: its value is determined based on file extension, for example,
- .txt: text/plain
- .pdf: application/pdf
- .xml: application/xml
COMPONENTS/item/COMP_SIZE: this is the file size. Map its value from header CamelFileLength.
CONTENT/item & CONTENT/item/LINE: This section contains the actual binary content of the file. The content must be split into multiple lines because the RFC structure expects the data in chunks.
Some custom UDFs are used in the message mapping to handle binary processing.
import com.sap.it.api.mapping.Output;
def String getHexValue(String arg1){
String hex = arg1.bytes.collect { String.format("%02X", it) }.join('')
return hex
}
def String getFileExtension(String fileName){
def extension = fileName.substring(fileName.lastIndexOf('.') + 1).toUpperCase()
return extension
}
def String getByteSize(String ediString){
Integer hexSize = ediString.bytes.size()
return hexSize + ''
}
def String base64Decode(String input) {
def base64String = input.replaceAll("\\s", "")
def base64Decoded = Base64.decoder.decode(base64String)
return new String(base64Decoded)
}
def void splitBinaryContent(String[] input, String[] interval, Output output) {
Integer intv = interval[0].toInteger()
String s = input[0]
Integer arrayLength = (int) Math.ceil(((s.bytes.size() / (double) intv)));
String[] result = new String[arrayLength];
int j = 0;
int lastIndex = result.length - 1;
for (int i = 0; i < lastIndex; i++) {
byte[] subArray = Arrays.copyOfRange(s.bytes, j, j + intv);
result[i] = new String(subArray, "UTF-8")
j += intv;
output.addValue(result[i]);
}
byte[] lastSubArray = Arrays.copyOfRange(s.bytes, j, s.bytes.size());
result[lastIndex] = new String(lastSubArray, "UTF-8");
output.addValue(result[lastIndex]);
}Testing the Integration
After deploying the iFlow:
- Upload a file to an SFTP server.
- The iFlow processes the request.
- The RFC adapter sends the request to SAP.
- The document is stored successfully.
The attachment can then be viewed in SAP using transaction OAOR.
Conclusion
In this blog post, we demonstrated how to upload binary files from SAP Cloud Integration to SAP using the RFC function module BDS_BUSINESSDOCUMENT_CREA_TAB.
Key takeaways:
- Binary content should be Base64 encoded before XML processing.
- The content must be converted and split into chunks for the RFC structure.
- Custom UDFs help with encoding, size calculation, and content splitting.
This approach can be used to attach documents to various SAP business objects via GOS. If you have questions or improvements, feel free to share them in the comments.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.