In this article, we’ll look at how to handle attachments in incoming messages in PI/PO interfaces. We will go through use cases that involve attachments; Java class used for processing the attachments; and methods of the Java class that can be used to process attachments.
Then, we will build a Java Mapping to read and copy the attachment payload from XI message to the target. Moreover, we’ll check step-by-step how to develop and configure the end-to-end interface in ESR and ID.
Use cases of Attachments in Integration Scenarios
When it comes to system integration, a lot of protocols have the capability of sending attachments with the main message payload. Therefore, when building SAP integration scenarios via SAP PI/PO, you will come across interfaces where attachments should be processed.
Here are some examples where attachments in the messages should be managed in SAP PI/PO. Additionally, you can read about attachment handling for SAP documents using GOS in the linked article.
Attachments in SOAP messages
SOAP (Simple Object Access Protocol) has the capability to exchange attachments with the main message payload. When integrating SAP with SOAP services, the interface should be able to read attachment data from SOAP message or write attachments to the SOAP message.
Zip File Processing
Usually, zipped or compressed files contain multiple files inside. For example, a zip file can contain one XML as the main payload and multiple PDFs. In such cases, the PDFs will be assigned to XI payload as attachments.
This article goes hand-in-hand with my previous post on how to process zip files in PI/PO.
Mails with Attachments
In most instances, email messages contain one or more attachments. When integrating email messages via Mail adapter, the interface should be built to handle attachments in the email.
Java Class InputAttachments
We can use the Java class interface InputAttachments and its methods to read attachments in XI message. Java class can be used in User-Defined Functions (UDF) or Java Mapping programs. This class is included in source path com.sap.aii.mapping.api.
The class has three methods to handle attachments in the XI payload. They are, getAllContentIds, areAttachmentsAvailable and getAttachment.
Method getAllContentIds
This method returns all the attachment IDs of the source payload as a collection of string. Each attachment in a source payload has a unique ID called content ID. Using this method, you fetch the content IDs of all the attachments in the XI message as a collection.
Method areAttachmentsAvailable
As the method name indicates, we can use this method to check if there are attachments in the XI payload. Further, attachments in the payload can be accessed from the message mapping program.
The mapping program can access the attachments in the payload only if the option “Read Attachment” is activated in the Operation Mapping.
Method getAttachment
This method returns the Attachment object of a specific content ID.
Syntax: Attachment getAttachment(String contentID)
The attachment object consists of a set of methods that can read the content of the attachment in different formats. Furthermore, it contains methods to identify the type of attachment.
Method Name | Syntax | Purpose | Return Type |
getContent | byte[] getContent() | Returns the actual content of the attachment as a byte array. | byte[] |
getContentType | String getContentType() | Returns the type of attachment. For example, pdf, txt, jpg, etc. | String |
getBase64EncodedContent | String getBase64EncodedContent() | Returns the actual content of the attachment as base64 encoded format. | String |
Base64 schema is a great way to handle attachments.
For more information about base64, you can read previous articles,
- Base64 encoding/decoding in SAP ABAP
- Java Mappings to decode Base64 and encode base64 schema
- UDF to encode and decode Base64
Integration Scenario Overview
To illustrate attachment handling, let’s assume we have an SFTP server where zip files are stored. Each zip file contains an Invoice XML and the corresponding PDF file of the invoice. We want to extract the zip files and transfer the Invoice XML and PDF to two different locations in the receiver SFTP server.
Sender SFTP adapter reads the zip file and unzips it using the adapter module AF_Modules/PayloadZipBean. After the zip file is unzipped, the source message will include both Invoice XML and PDF.
Let’s make use of two mapping programs to handle the zip file content.
- A graphical message mapping program to map the source invoice XML to receiver invoice XML format.
- A Java Mapping program to read the PDF attachment data from the source message and copy the content to the output stream.
If you want to send the PDF to an SAP back-end system as a proxy message, one possible method is to convert the attachment content to base64 format using getBase64EncodedContent.
Java Mapping to Handle Attachments in the Source Message
Using the Java interface InputAttachment we discussed earlier in the article, the Java Mapping program reads the content of the PDF attachment and copies it to the output stream.
First, the handler for attachment is generated from the method getInputAttachments. Second, the attachment handler is looped to get content IDs of the attachments. In our scenario, there is only one attachment in the payload. Finally, the content of the attachment is read by applying the method getContent and assigned to the output.
package readAttachment; import java.io.*; import com.sap.aii.mapping.api.*; public class CopyPDFtoPayload extends AbstractTransformation{ @Override public void transform(TransformationInput transformationInput, TransformationOutput transformationOutput) throws StreamTransformationException { try { //Get the handler for processing the attachments of source message InputAttachments attachment = transformationInput.getInputAttachments(); InputStream inputstream = transformationInput.getInputPayload().getInputStream(); OutputStream outputstream = transformationOutput.getOutputPayload().getOutputStream(); //Fetch the collection of attachments in the source message for (String id : attachment.getAllContentIds(false)) { //Read the content of the attachment and assign the content to output outputstream.write((attachment.getAttachment(id)).getContent()); } } catch (Exception exception) { getTrace().addDebugMessage(exception.getMessage()); throw new StreamTransformationException(exception.toString()); } } }
Configuration in Enterprise Service Repository
Now let’s look at the step-by-step configuration in ESR.
Create a Source Message Type
We are representing the format of the invoice XML in the sender message type.
For the source Message Type of the main payload refer to this article on zip file handing integration scenario.
Build an Outbound Service Interface
Using the sender Message Type created in the previous step, develop the sender Service Interface.
Define Target Message Types
We will create two target message types: one for invoice XML receiver and the other one for the PDF. But the actual message format with the elements/attributes of the Message type used for PDF receiver is irrelevant as we are copying the content of the PDF to the output stream. Since a message mapping program in SAP PI/PO requires a Message Type, we have to create one.
Message Type for PDF: PDFPayload
Configure Two Inbound Service Interfaces
We will build two Inbound Service interfaces: one for invoice XML receiver and the other one for the PDF receiver.
Inbound Service Interface for PDF attachment: PDFPayload_Inb_Async
Check the post about zip file processing in SAP PI/PO for invoice XML service interface development steps.
Message Mapping and Operation Mapping
We will build a graphical mapping program in the usual way to map the sender invoice XML format to the target invoice XML format. In this example, the message formats at the sender and receiver are exactly the same, therefore, the mapping is one-to-one.
Build the Imported Archives for Attachment Handling
Using the Java code provided in the article, configure Imported Archives. We will name the Imported Archive or the Java Mapping as copyPDFAttachment.
If you are new to Java Mapping, check out my article where I have described how to create a Java Mapping step-by-step using NWDS Eclipse.
Configure the Operation Mapping for PDF Attachment Handling
Using the Java Mapping developed in the step above, create an Operation Mapping between sender Outbound Service Interface and PDF receiver Inbound Service Interface. Let’s name the Operation Mapping PDFAttachment_to_Payload.
The target data structure “PDFPayload” is obsolete as we are using a Java Mapping to copy the PDF content.
iFlow and Integrated Configuration Development Steps
Now that we have designed all the necessary objects in ESR, let’s configure the end-to-end iFlow in NWDS Eclipse.
Attachment Handling iFlow
Here we have the end-to-end attachment handling interface implemented as an iFlow via Eclipse NWDS.
Sender System and Sender Service Interface
The sender system is BC_TEST_SENDER and the Inbound Service Interface name is InvoiceXMLwithAttachment_Out_Async.
Attachment Sender sFTP Adapter
Sender Communication Channel is of adapter type SFTP and its name is SFTP_s_ZIP. This Channel picks up zip files from SFTP server.
How to configure the adapter module of the sender SFTP Communication Channel to unzip the input message is provided in this post.
Attachment Receiver Service Interfaces
Attachment receiver Inbound Service Interface is PDFPayload_Inb_Async and the receiver component is BC_TEST_RECEIVER.
Attachment PDF Receiver Communication Channel
SFTP_r_PDF Communication channel writes the PDF files to the specified folder.
Attachment Handling Operation Mapping
Testing the Integration Scenario
Let’s place a zip file with invoice XML and PDF in zip file sender SFTP folder.
First, invoice.zip will be unzipped by the sender SFTP adapter using the adapter module PayloadZipBean. Invoice.xml will be assigned as the main payload of the XI message and PDF will be assigned to the message as the first attachment.
Attachment Handling Interface Processing Steps
Let’s look at the processing pipeline of the interface in the PI/PO message monitor.
Message Processing Overview in Message Monitor
File Unzipped from Sender Adapter
Main Payload and Attachment in XI Message Content
Inbound Message Split into Two
Attachment Processed by Java Mapping
PDF Payload Delivered to Attachment Receiver Communication Channel
Attachment PDF Saved in Receiver SFTP Location
Tips and Tricks:
Since the XI message holds two payloads and we use two separate receiver channels to send them to the target we need to deactivate the attachment storing option in the Receiver Communication Channel. If the option “Store Attachment” is activated at the receiver, each receiver Communication Channel will receive both payloads.
I hope you learned something new and now you know how to handle attachments in SAP PI/PO when building interfaces. It is important to understand the functionality of Java class “InputAttachments” and its methods to develop your own Java Mapping programs.
Have you tried any other integration strategies to process messages with attachments? Please, leave a comment below if you have. Also, if you have any questions, leave a comment below.
Hi I need to know how PI/PO work with RESTFUL service?eg:JSON request and respond.
Ho PI/PO will work with SAP service layer or it is a different technology work with only SAP DB?
What condition you are using while routing xml to one receiver branch and pdf to other receiver branches?. I think condition is mandatory and very crucial step here.
Hello Madhu,
Sender message is the same for both mapping programs. Hence, we do not need a condition to route the message. PDF content is copied over to receiver using the java mapping.
Cheers,
Isuru
Hi Isuru ,
Very good and informative blog ..could you please write some blogs on REST Adapter features like dynamic URL handling etc..
Hi Isuru,
Thanks for your efforts and its very clear understanding the overall scenario. I have a query here. As per requirement we have two receivers one is to send main payload (Invoice XML) and second receiver is for PDF attachments. Suppose let’s assume we have multiple PDF attachments and activated Store attachment check at receiver side. Now those PDF documents are simply stored at target location as an individual or those PDF attachments are again in .ZIP type at target side?
i really appreciate your effort for this article, this post is helpful for me. Each and every points covered with suitable information, i loved reading it.
Hi Isuru,
I have a scenario that i need to call the REST API and download the zip attachment on to the file system. Zip file can contain any combination of document types so this does not need to be passed in the payload back to ECC unless the requirement changes. But i will still need to pass back a dummy structure back so the UDF i need help with should download the zip file and also send a dummy payload structure back. The flow is Proxy to REST if the UDF can be managed OR REST Polling to File. I tried the REST polling to File but the zip that is being created is giving the error as invalid so if you can help me with this then i do not need the UDF option as of now. I have not been able to get any help from anyone. Please advise and help me.
Hi, I have a FILE to REST scenario, the only thing that is transferred is a zip file to the REST API. I have configured, as per the above, it’s picking up the file and Executing Request Mapping with the correct one, but I’m getting an error. MappingException: com.sap.aii.utilxi.misc.api.ResourceException: Could not determine mapping steps for message 81617242-ff8f-11ed-ca84-00000082812e.
Have you any advice please?