cancel
Showing results for 
Search instead for 
Did you mean: 

File to SOAP as attachment with authentication over SOAP Header

Former Member
0 Kudos

Hello experts - I'm looking for some guidance.

I have a File to SOAP async scenario.

  • The file is to be sent as an attachment over SOAP.
  • The file is a txt based flat file and the attachment needs to reflect the same source file, with no content change.
  • There is some basic mapping needed so I can't do a pass-through (no ESR) scenario.
  • For the mapping, I don't need any info from the source message content, but I'll need the file name, which I'm currently getting it using ASMA.
  • The SOAP authentication happens through wsse Security over the SOAP header.
  • Apparently using AXIS to build the SOAP header to add the wsse structure is not an option as I had issues in order to implement it. SAP suggested to upgrade the current messaging component, NW 7.3 SP7 patch level 4, to patch level 38 or higher. I'd avoid such upgrade for now due to interdependencies.
  • I'm flagging to "Use SAP XML Toolkit" and "Read Attachments" in the OM; the "Do Not Use SOAP Envelope" and "Keep Attachments" in the receiver SOAP channel.

I'm facing 2 issues:

  • I'm using a custom adapter module (code below) to create the attachment based on the payload, but that's no good as I need the original source file. How can I get it as an attachment?
  • The SOAP receiver service seems to not recognize the attached file as the attachment content ID is going as "cid:payload-[msgId]@sap.com", where I'd need it to go as cid:[filename].

I assume the xlink:href should be "cid:COB04113.REM" for the example above.

When a message is sent through, there is no failure and the SOAP call seems to complete succesfully, but I believe the receiver WS is not accepting or discarding the sent attached file as the file name does not match the attachment content ID value.

What suggestions do you have?
Thank you
Elison

Details:

Message Mapping target structure
I'm using ASMA to get the filename and building the content field as "cid:[filename]". Constant for the destination.

After the XSLT mapping I get the following message structure, which is correct:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header>
      <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <wsse:UsernameToken>
            <wsse:Username>user</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText
  ">password</wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
   </soapenv:Header>
   <soapenv:Body>
      <ns1:uploadFile xmlns:ns1="urn:ServiceWS">
         <file>
            <filename>COB04113.REM</filename>
            <content>cid:COB04113.REM</content>
         </file>
         <destination>INBOX</destination>
      </ns1:uploadFile>
   </soapenv:Body>
</soapenv:Envelope>

Details:

Bean for custom adapter module to create the attached file (credits amitsrivastava5)

/**
*
*/
package com.sap.adaptermodule;
import java.rmi.RemoteException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import com.sap.aii.af.lib.mp.module.ModuleContext;
import com.sap.aii.af.lib.mp.module.ModuleData;
import com.sap.aii.af.lib.mp.module.ModuleException;
import com.sap.aii.af.service.auditlog.Audit;
import com.sap.engine.interfaces.messaging.api.Message;
import com.sap.engine.interfaces.messaging.api.MessageKey;
import com.sap.engine.interfaces.messaging.api.MessagePropertyKey;
import com.sap.engine.interfaces.messaging.api.Payload;
import com.sap.engine.interfaces.messaging.api.XMLPayload;
import com.sap.engine.interfaces.messaging.api.auditlog.AuditLogStatus;
/**
* @author amitsrivastava5
*
*/
public class SavePayloadBean implements SessionBean {
    /* (non-Javadoc)
     * @see javax.ejb.SessionBean#ejbActivate()
     */
    @Override
    public void ejbActivate() throws EJBException, RemoteException {
        // TODO Auto-generated method stub
    }
    /* (non-Javadoc)
     * @see javax.ejb.SessionBean#ejbPassivate()
     */
    @Override
    public void ejbPassivate() throws EJBException, RemoteException {
        // TODO Auto-generated method stub
    }
    /* (non-Javadoc)
     * @see javax.ejb.SessionBean#ejbRemove()
     */
    @Override
    public void ejbRemove() throws EJBException, RemoteException {
        // TODO Auto-generated method stub
    }
    /* (non-Javadoc)
     * @see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)
     */
    @Override
    public void setSessionContext(SessionContext arg0) throws EJBException,
            RemoteException {
        // TODO Auto-generated method stub
    }
    public void ejbCreate() throws javax.ejb.CreateException {
      
    }
    public ModuleData process(ModuleContext mc, ModuleData inputModuleData) 
    throws ModuleException { 
        Object obj = null;
        Message msg = null;
        MessageKey key = null;
        String FileName = "";
        MessagePropertyKey FileKey = null;      
        try {
        obj = inputModuleData.getPrincipalData();
        msg = (Message) obj;
        key = new MessageKey(msg.getMessageId(), msg.getMessageDirection());
        FileKey = new MessagePropertyKey("FileName", "http://sap.com/xi/XI/System/File");
        // getting FileName from ASMA parameters
        FileName = msg.getMessageProperty(FileKey);
        // Returns the main document as XMLPayload. 
    XMLPayload xpld = msg.getDocument(); 
    byte[] inpbyt = xpld.getContent(); 
    Audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS, "Input file read successfully");  
    //Archiving target file on FTP server 
    xpld.setContent(inpbyt); 
    Payload ftpFilePayload = msg.createPayload();
    ftpFilePayload.setName(FileName);                              
    ftpFilePayload.setContentType("text/plain;charset = \"UTF-8\"");
    ftpFilePayload.setContent(inpbyt);      
    ftpFilePayload.setDescription("Attachment");      
    msg.addAttachment(ftpFilePayload);
    // Sets the principle data that represents usually the message to be processed 
    inputModuleData.setPrincipalData(msg); 
    }catch (Exception e) { 
    Audit.addAuditLogEntry(key, AuditLogStatus.SUCCESS,    "Module Exception caught:"); 
    ModuleException me = new ModuleException(e); 
    throw me; 
    } 
    return inputModuleData; 
    } 
    } 

XSLT code for wsse Security to authenticate the soap call at the receiver WS.

<?xml version="1.0" encoding="UTF-8"?>  
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"      
    xmlns:urn="urn:ServiceWS"
    xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"     
    version="1.0">   
 <xsl:output method="xml" version="1.0" encoding="UTF-8" />    
 <xsl:attribute-set name="attr-soap">   
  <xsl:attribute name="soapenv:mustUnderstand">1</xsl:attribute>  
 </xsl:attribute-set>    
 <xsl:attribute-set name="attr-pasw">    
  <xsl:attribute name="Type">http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText
  </xsl:attribute>  
 </xsl:attribute-set>   
 <xsl:template match="/">    
  <soapenv:Envelope>       
   <soapenv:Header>     
    <xsl:element name="wsse:Security"
        use-attribute-sets="attr-soap">
     <xsl:element name="wsse:UsernameToken">
      <xsl:element name="wsse:Username">user</xsl:element>          
      <xsl:element name="wsse:Password" use-attribute-sets="attr-pasw">password</xsl:element>                        
     </xsl:element>               
    </xsl:element>    
   </soapenv:Header>       
   <soapenv:Body>         
	<xsl:copy-of select="*"/>         
   </soapenv:Body>   
  </soapenv:Envelope>     
 </xsl:template>  
</xsl:stylesheet>

Accepted Solutions (0)

Answers (0)