Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
3,357

Background


During an implementation of integration between Ariba Cloud Integration gateway  (Using SAP CPI)and S4 HANA Cloud system, we  identified that even though the SOAP adapter in SAP CPI does support MIME messages and is SOAP 1.2 compliant, it doesn’t support MTOM messages. S/4 HANA Cloud system supports MTOM MIME messages received via SOAP adapter and was expecting the SOAP MIME message in MTOM format this integration scenario.

Upon recommendation , we were able to achieve the integration by building a MIME SOAP envelope in compliance with MTOM and delivery via HTTP adapter to S4 HANA Cloud system.

Implementation


I have used groovy script to build custom MIME envelope in compliance with MTOM.

MTOM requirements


For MTOM SOAP content-type should be as below

  • Content-Type: application/xop+xml; charset=utf-8; type="text/xml"


Integration Flow


Pre-Requisites

S/4 HANA Cloud requires the following additional headers in the MIME

Content-Length of each MIME part

Content-Length of complete MIME Envelope

Here is the iflow implementation of the MIME envelope



 

  • Receive MIME Envelope – via HTTP Sender Adapter

  • Parse the MIME using MIME Multipart Decoder Component provided by CPI

  • Script to get the size of actual payload

  • Script to build the MIME envelope in compliant with MTOM

  • Script to get the size of Complete MIME SOAP Envelope

  • Deliver it to target via HTTP Receiver Adapter using Request/Reply component and capture the Response received .


 

Script to get payload size and to get size of the complete MIME Envelope


import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {
//Body
long payloadSize = message.getBodySize();
String PayloadSize = payloadSize.toString();

message.setHeader("PayloadSize", PayloadSize);

return message;
}

Script to build MIME Envelope


import com.sap.gateway.ip.core.customdev.util.AttachmentWrapper;
import com.sap.gateway.ip.core.customdev.util.Message;
import org.apache.camel.impl.DefaultAttachment;
import javax.mail.util.ByteArrayDataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.camel.Attachment;
import javax.activation.DataHandler;
import java.util.Iterator;
import org.apache.commons.io.IOUtils;
import java.lang.Byte;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import java.lang.StringBuilder;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

def Message processData(Message message) {
//Body


byte[] payload = message.getBody(byte[].class);
String attType
String attName
String attSize
String attContentId
String source = null
def map = message.getHeaders();

String SOAPEnvelopeSize = map.get("PayloadSize")

// Data source
MimeMessage mimeMessage = new MimeMessage(source);
def MimeMultipart mimeMultipart = new MimeMultipart("related");

//SOAP Payload
def MimeBodyPart soapapayload = new MimeBodyPart();
soapapayload.setHeader("Content-Length", SOAPEnvelopeSize)

ByteArrayDataSource soapDataSource = new ByteArrayDataSource(payload, "application/xop+xml")
soapapayload.setDataHandler(new DataHandler(soapDataSource));
soapapayload.setHeader("Content-Type", "application/xop+xml; charset=utf-8; type=\"text/xml\"")
mimeMultipart.addBodyPart(soapapayload)

//get and set attachments
def attMap = message.getAttachments();
def AttCount = attMap.size()
if(AttCount > 0)
{

Map<String, AttachmentWrapper> attMapN = message.getAttachmentWrapperObjects();
Iterator<Entry<String, AttachmentWrapper>> attIteratorN = attMapN.entrySet().iterator();
int j = 1;
while(attIteratorN.hasNext())
{

Entry<String, AttachmentWrapper> entryN = attIteratorN.next();
AttachmentWrapper attachment = entryN.getValue();
DataHandler dataHandler = attachment.getDataHandler();
InputStream inputStream = dataHandler.getInputStream();
byte[] bytes = IOUtils.toByteArray(inputStream);
int EachAttachmentSize = bytes.length
attSize = Long.toString(EachAttachmentSize)
def MimeBodyPart soapAttachmentBodyPart = new MimeBodyPart();
Collection<String> headerList = attachment.getHeaderNames();
soapAttachmentBodyPart.setDataHandler(dataHandler)
for (String attachmentHeaderName : headerList) {
String attachmentHeaderValue = attachment.getHeader(attachmentHeaderName);
soapAttachmentBodyPart.addHeader(attachmentHeaderName, attachmentHeaderValue);
}
mimeMultipart.addBodyPart(soapAttachmentBodyPart)
j++;
}
}

StringBuilder builder
String searchStr
String replaceStr
String resultString

String mimeContentType = mimeMultipart.getContentType();

builder = new StringBuilder(mimeContentType);
searchStr = "multipart/related"
replaceStr = "Multipart/Related;type=\"application/xop+xml\"; start-info=\"text/xml\""
resultString = stringReplaceAll(builder, searchStr, replaceStr)

message.setHeader("Content-Type",resultString);
ByteArrayOutputStream boas = new ByteArrayOutputStream();
mimeMultipart.writeTo(boas);
message.setBody(boas);
message.setHeader("accept","application/xop+xml ,text/xml")
return message;
}

def stringReplaceAll(builder, String from, String to)
{
int index = builder.indexOf(from);
while (index != -1)
{
builder.replace(index, index + from.length(), to);
index += to.length();
index = builder.indexOf(from, index);
}
String replacedString = new String(builder);
return replacedString;
}


 

Conclusion


This is a substitute solution for implementing MTOM MIME message generation in SAP CPI. The MIME Envelope script can be modified as per requirement .

2 Comments