We don’t have SFTP adapter Module in SAP PI 7.0 so if there is any requirement to connect a SFTP server then either we need to purchase an external adapter or we could create a module in JAVA.

I was having a requirement of placing a file over SFTP server so to solve that I wrote a JAVA code for SFTP adapter module.

Hopefully this will help others to create modules for their requirement.

Parameter Configuration in PI receiver Channel:

hahahah.PNG

/**
* @author ashutosh.a.upadhyay
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package com.sftp;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;

import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.sap.aii.af.mp.module.Module;
import com.sap.aii.af.mp.module.ModuleContext;
import com.sap.aii.af.mp.module.ModuleData;
import com.sap.aii.af.mp.module.ModuleException;
import com.sap.aii.af.ra.ms.api.Message;
import com.sap.aii.af.ra.ms.api.MessageDirection;
import com.sap.aii.af.ra.ms.api.XMLPayload;
import com.sap.aii.af.service.auditlog.Audit;
import com.sap.aii.af.service.auditlog.AuditDirection;
import com.sap.aii.af.service.auditlog.AuditLogStatus;
import com.sap.aii.af.service.auditlog.AuditMessageKey;
/**
* @ejbHome <{com.sap.aii.af.mp.module.ModuleHome}>
* @ejbLocal <{com.sap.aii.af.mp.module.ModuleLocal}>
* @ejbLocalHome <{com.sap.aii.af.mp.module.ModuleLocalHome}>
* @ejbRemote <{com.sap.aii.af.mp.module.ModuleRemote}>
* @stateless
*/
public class SFTPAdapterModule implements SessionBean, Module {
private SessionContext myContext;

AuditMessageKey amk;

public void ejbRemove(){
}
public void ejbActivate(){
}
public void ejbPassivate(){
}
public void setSessionContext(SessionContext context){
  myContext = context;
}
public void ejbCreate() throws CreateException {
}

public ModuleData process(ModuleContext moduleContext,ModuleData inputModuleData)throws ModuleException {
  try {
  Object obj = inputModuleData.getPrincipalData();
  Message msg = (Message) obj;
  String SFTPHOST = (String) moduleContext.getContextData(“SFTPHostorIP”);
  String SFTPPORT = (String) moduleContext.getContextData(“SFTPPort”);
  String SFTPUSER = (String) moduleContext.getContextData(“SFTPUserName”);
  String SFTPPASS = (String) moduleContext.getContextData(“SFTPpassword”);
  String destDir =  (String) moduleContext.getContextData(“TargetLocation”);
  String fileName = (String) moduleContext.getContextData(“SFTPFileName”);
    
    if (msg.getMessageDirection()== MessageDirection.INBOUND)
    amk = new AuditMessageKey(msg.getMessageId(),AuditDirection.INBOUND);
    else
    amk = new AuditMessageKey(msg.getMessageId(),AuditDirection.OUTBOUND);
     
    XMLPayload xp = msg.getDocument();
   
 
  Hashtable mp = (Hashtable) inputModuleData.getSupplementalData(“module-parameters”);
  if (fileName ==””){
   fileName = (String) mp.get (“FileName”);
  }
  if (destDir ==””){
    fileName = (String) mp.get (“Directory”);
  }  
    Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS,”SFTP adapter module called….”);
  
    if (xp != null){
     Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS,”Connecting to SFTP….”);
   byte by[] = convert(xp.getInputStream(),SFTPHOST,SFTPPORT,SFTPUSER,SFTPPASS, fileName, destDir);
     Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS,”File placed successfully”);
     xp.setContent(by);
    }
  
    inputModuleData.setPrincipalData(msg);
    Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS,”Principle data is set successfully.”);
    }
    catch (Exception e){
  Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS,”Module Exception Caught .”);
  ModuleException me = new ModuleException(e);
  throw me;
    }
    return inputModuleData;
}

public byte [] convert(InputStream inputstream,String host,String port, String username,String password, String fileName, String dir) throws Exception {
Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;
String file =””;
  try
  {  
  Date date = new Date();
  SimpleDateFormat sdf = new SimpleDateFormat(“yyyyMMddHHmmssSSS”);
  String formattedDate = sdf.format(date);
  fileName = fileName+formattedDate;

  JSch jsch = new JSch();
  int portNo = Integer.parseInt(port);
  session = jsch.getSession(username,host,portNo);
  session.setPassword(password);
  java.util.Properties config = new java.util.Properties();
  config.put(“StrictHostKeyChecking”, “no”);
  Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS,”Establishing Connection…”);
  session.setConfig(config);
  session.connect();
  Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS,”Session Established”);
  channel = session.openChannel(“sftp”);
  Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS,”Connecting the channel..” );
  channel.connect();
  channelSftp = (ChannelSftp) channel;
  Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS,”Hitting the directory” );
 
  channelSftp.put(inputstream,fileName); 
  Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS,”File placed..” );
     
  channelSftp.disconnect();
  Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS,”Channel Disconnected…” );
    
  session.disconnect();
  sdf = new SimpleDateFormat(“dd/MM/yyyy”);
  formattedDate = sdf.format(date); 
  file = “<FileName> file placed to SFTP server at “+formattedDate;
 
  inputstream.close();
  Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS,”Server Disconnected…” );
}
    catch (Exception e) {
    Audit.addAuditLogEntry(amk, AuditLogStatus.SUCCESS,”Exception in Convert Method.”);
    channel.disconnect();
  session.disconnect();
}
return file.getBytes();
}
}

To report this post you need to login first.

22 Comments

You must be Logged on to comment or reply to a post.

  1. Bryan Sanches

    Hello, having issues with this module adapter using Receiver File.  I get error in the convert method.

    byte by[] = convert(xp.getInputStream(),SFTPHOST,SFTPPORT,SFTPUSER,SFTPPASS, fileName, destDir);


    here are my paramters

    SFTPHost: IP address

    SFTPPORT: 22

    SFTPUSER: username

    SFTPASS: password

    filename: delivery.xml

    destdir: /norske

    Any ideas why I am experiencing this error?

    (0) 
  2. Bryan Sanches

    Hello Ashutosh,

    Got the SFTP Module to work now.  But do you experience the behavior that the messages using the SFTP Module are having status = WAIT instead of Successful?

    (0) 
    1. Ashutosh Upadhyay Post author

      If I am not wrong, you are using JDBC adapter and SFTP module configured in it. The wait status is because of the database issue, you must see the error details in the Audit log of the messages in waiting.

      (0) 
  3. Bryan Sanches

    Here is the error message in the Message Logs: Delivery of the message to the application using connection File_http://sap.com/xi/XI/System failed, due to: com.sap.aii.af.ra.ms.api.DuplicateMessageException: Message ID e46c0191-c998-bdf1-bc4e-0017a477def1(INBOUND) already exists in database: com.sap.sql.DuplicateKeyException: ORA-00001: unique constraint (UNKNOWN.obj#=61379) violated.

    (0) 
    1. Ashutosh Upadhyay Post author

      This seems to be DATABASE Error, in my module I used SFTP module in FTP adapter and placing a log file just.

      The above error is not because of SFTP module, your JDBC channel is posting same data to the database.

      (0) 
    1. Ashutosh Upadhyay Post author

      Hi Bryan,

      Thanks for the Audit log, now I understood the error. The issue is with the duplicate message entry inside of the PI database. You must have tried reprocessing the messages in the wait status. Could you please look out the specific message IDs mentioned in erroneous messages and cancel them or create a new message entry for next messages.

      Ashutosh

      (0) 
  4. Bryan Sanches

    Hello Ashutosh,

    Cancelled the message and did a re-sent from the source system.  Here are the message logs

    FTP channel4.JPG

    FTP channel5.JPG

    It seems that after successfully placing the file via SFTP in the target system, it will use then try to connect to the FTP system using the standard way; causing the message to be in WAIT

    (0) 
    1. Ashutosh Upadhyay Post author

      Try to use NFS feature first. Test if you are able to place a file at local drive.

      Then move to FTP with correct parameters and file settings. The issue looks like a FTP server issue.

      (0) 
      1. Bryan Sanches

        Hello Ashutosh,

        Was able to get it to work now, thanks.  I thought there was a way to stop using the CallSapAdapter module.  So as a workaround, I used the email adapter itself, since there are FTP and NFS is not permitted.

        (0) 
  5. Peter Wallner

    Hello,

    works well 🙂

    I found one flaw though:

    In your convert() method the “dir” is never read (which is the “destDir”).

    So I added the following line “channelSftp.cd(dir);”

    to the convert() method.

    Best regards,

    Peter

    (0) 

Leave a Reply