Integration Blog Posts
cancel
Showing results for 
Search instead for 
Did you mean: 
536

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.

qiangwan87_0-1773572149801.png

Processing Steps

qiangwan87_1-1773572262161.png

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. 

qiangwan87_2-1773572399798.png

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]);
}

qiangwan87_3-1773573645896.png

qiangwan87_4-1773573710713.png

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.

qiangwan87_5-1773573928611.png

qiangwan87_6-1773574250613.png

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.