Retaining SOAP Adapter Attachment Names
As per thread: Stefan Grube mentioned in the thread, this is the default SOAP adapter behavior since it was hardcoded in SOAP adapter for incoming attachments to XI. But most of the times, the business needs the original attachment names at the receiving target application. So, how can we achieve this.
discussion, SOAP sender Adapter always replaces the incoming attachment names with attachment-1, attachment-2 etc.. And asIn this blog, I am providing UDF code snippet using which we can retain original attachment names in the mapping by reading incoming attachments using mapping API for attachments (applicable from PI7.1 onwards). Also, with this procedure we can overwrite existing attachments with any content as bytes. Note:- the same can be achieved with a java mapping/XSLT with java enhancements as well.
String attachmentID = null;
java.util.Map map;
AbstractTrace trace;
//gets the input attachment from the source message
GlobalContainer globalContainer = container.getGlobalContainer();
InputAttachments inputAttachments = globalContainer.getInputAttachments();
OutputAttachments outputAttachments = globalContainer.getOutputAttachments();
trace = container.getTrace();
//map = globalContainer.getParameters();
try
{
//checks for the availability of attachments in the input message
if(inputAttachments.areAttachmentsAvailable())
{
trace.addInfo("Attachments Available");
//gets the attachmentIds and store it in an Object array
Collection<String> CollectionIDs = inputAttachments.getAllContentIds(true);
Object[] arrayObj = CollectionIDs.toArray();
//Loops at the input attachments to get the content of the attachment
for(int i =0;i<arrayObj.length;i++)
{
attachmentID =(String)arrayObj[i];
trace.addInfo((i+1) + ") Attachment Name: " + attachmentID);
Attachment attachment = inputAttachments.getAttachment(attachmentID);
String contentType = attachment.getContentType();
//To retain attachment names in mail adapter (receiver). Updated on 3:35 PM 09/30/2013 IST.
//Use charset only in case of textual attachments e.g., XML, flatfiles
contentType = contentType + ";charset = \"UTF-8\";"+ "name=\"" + attachmentID + "\"";
byte[] attachmentBytes = attachment.getContent();
Attachment renameAttachment = outputAttachments.create(attachmentID, contentType, attachmentBytes);
outputAttachments.setAttachment(renameAttachment);
//remove each attachment if required. Uncommonent below
//trace.addInfo("Removing Attachment no: " + (i+1) + " & Name: " + attachmentID);
//outputAttachments.removeAttachment(attachmentID);
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return var1;
Attachments sent from SOAP UI as SOAP message to XI.
With the above UDF in the graphical mapping, the results will be as shown below for the inbound/mapping pipeline stages in MONI
Update: 3:35 PM 09/30/2013 IST
Code updated, to retain attachments names in case of receiver mail adapter. Line no: 30 in above UDF code snippet should be used in either of the below forms.
1) Code for textual attachments e.g., XML, flat etc.. with required encoding e.g., UTF-8
contentType = contentType + “;charset = \”UTF-8\”;“+ “name=\”” + attachmentID + “\””;
2) Code for binary attachments e.g., pdf’s, images etc..:
contentType = contentType + “;”+ “name=\”” + attachmentID + “\””;
Regards,
Praveen Gujjeti
Nice work Praveen. Thanks. I see you return variable var1. But I don't see your declaration and values return via it. Can you please correct it?
Thanks Bhaskar. Yeah, in a way you are right as I did not put much effort on UDF creation in this blog. As you know, var1 is the default first input when we define any new UDF in graphical mapping and hence the defined UDF with above code snippet in the blog can be used between any nodes in graphical mapping.
We can also remove the var1 from both UDF signature and from the code thus by making a generating UDF and it can be mapped to any target node 🙂
Best Regards,
Praveen Gujjeti
Hi Praveen,
I have the following scenario SOAP with attachment <--> PI <--> Proxy, the version of PI is 7.1
In the mapping I used the UDF that you provide to map the root node of the source message with the root node of target message, that's right?
When I test the scenario with SoapUI, in the Monitor of PI after Request Message Mapping, I see in the Payload "attachment-1" and not the name of the attachment.
What I am doing wrong?
Thanks a lot.
Regards.
Rodrigo.
Hi Rodrigo,
Have you enabled "Read Attachments" option in interface/operation mapping.
Regards,
Praveen Gujjeti
Thank you so much Praveen, I forget to enable this option. Now it work.
Regards.
Rodrigo.
Cheers 🙂
good one. just read this blog...very nice work. you rock as usuall...!
but i would prefer to have a simpler java mapping for this 😉 ..!
Thanks Senthil for your feedback. But, may I know why you are preferring a java mapping instead a simple UDF with Graphical mapping 😉
Regards,
Praveen Gujjeti
Hi Praveen Gujjeti
i am having soap to proxy interface asynchronous with attachments in 7.11. initially i was doing this interface with no mapping as i did not need to maintain attachment name. input xml has 5 fields and size of attachments is 20 MB.
now i have to to maintain the sender attachment name.If i go for graphical mapping with above UDF, will it have any impact on performance?
or is it good to go for java mapping?
Regards,
Muniyappan.
Hi Muniyappan,
Is your main payload is 20 MB or attachment?
If your payload is minimal in size, and you are only dealing with attachment 20 MB size, then I don't think UDF code should be a problem, unless your production system has huge number of large message size interfaces running in the same time period as your new interface.
What is the frequency of your new interface?
Also, can you post your requirement as a question in forum, to invite betters solutions from experts
Regards,
Praveen Gujjeti
Hi Praveen,
Thanks for you reply.
Attachment size is 20 MB. payload is very less, hardly 6 fields.
i am checking with business about frequency. once i get enough info i will post.
Regards,
Muniyappan.
Nice Blog Praveen..
Nice one
Informative blog Praveen.. Keep it up..
Thanks Bhargava
Helpful blog. Keep blogging
Hi all,
I am facing problem to add attachement. This is the senario :
in my sender I use 'keep attachement'.
I get the WSDL from the sender agrement in order to test with SOAPUI.
My WSDL, should contain any information about the attachement ?
Hi praveen,
Will it work filename with spaces? web service is sending the file i.e Split command.txt.but udf is taking only Split
Hi Muni,
The problem is not with UDF, the inbound attachment content ID coming as just Split, but the actual name you have it under contentType, change the for loop section to below.
for (int i = 0; i < arrayObj.length; i++) {
attachmentID = (String) arrayObj[i];
trace.addInfo((i + 1) + ") Attachment Name: " + attachmentID);
Attachment attachment = inputAttachments.getAttachment(attachmentID);
contentType = attachment.getContentType();
String newAttachmentID =
contentType.replaceAll("\"", "").substring(contentType.lastIndexOf("=") + 1);
contentType = contentType.substring(0, contentType.indexOf(";"));
contentType =
contentType + ";charset = \"UTF-8\";" + "name=\"" + newAttachmentID + "\"";
byte[] attachmentBytes = attachment.getContent();
// remove each attachment if required. Uncommonent below
trace.addInfo("Removing Attachment no: " + (i + 1) + " & Name: " + attachmentID);
outputAttachments.removeAttachment(attachmentID);
Attachment renameAttachment =
outputAttachments.create(newAttachmentID, contentType, attachmentBytes);
outputAttachments.setAttachment(renameAttachment);
}
Regards,
Praveen.
Hi Praveen,
I have similar requirement in SFTP adapter. I am trying to read the name of the attachement, which is .txt file. Since we do not have a property like getName for attachment, I am using your logic in UDF in graphical mapping to get attachement name from content type.
However i see PI is behaving weirdly. The content type data is sometimes populated with name information and sometimes it is not. I get below info in content type -
"application_octet-stream". No information regarding the name of the file.
PI version : 7.3 (dual stack)
Any clues what could be the issue?
Thanks,
Anand
Converting Binary payload(in a field) to .docx and .xlsx and send it as an attachment with SOAP adapter. Hello Parveen,
Thanks for an informative blog.
I have an urgent requirement wherein I need to rename an attachment and I have used similar approach to create the attachment through UDF in PI but the name of attachment is not changing.
Also, I'm not getting attachment from ECC ,the file is coming in binary format from ECC to PI and we are extracting data from a particular field and creating attachment out of it.
Please refer the below question link for details:
http://scn.sap.com/thread/3955194
I will be thankful if you can provide some help on it.
Thanks,
Indu Khurana.,