Skip to Content
Author's profile photo Former Member

SFTP Adapter Module in SAP PI 7.0

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();
}
}

Assigned Tags

      22 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Good to see Java code for SFTP Adapter module. Thanks for sharing it. 🙂

      Author's profile photo Sandeep Maurya
      Sandeep Maurya

      Hi Ashutosh!!

      In above example you are using file receiver adapter?

      Thanks,

      Sandeep Maurya

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Sandeep,

      Yes the adapter is File adapter.

      Regards,

      Ashutosh

      Author's profile photo Aman Gupta
      Aman Gupta

      Good Work Ashutosh.. thanks for sharing

      Thanks,

      Aman

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Thanks Aman

      Author's profile photo Former Member
      Former Member

      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?

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Bryan,

      Please post the error details then I can help in fixing it.

      Ashutosh

      Author's profile photo Former Member
      Former Member

      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?

      Author's profile photo Former Member
      Former Member
      Blog 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.

      Author's profile photo Former Member
      Former Member

      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.

      Author's profile photo Former Member
      Former Member
      Blog 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.

      Author's profile photo Former Member
      Former Member

      Hello,

      Actually I am using the Receiver File Adapter using FTP Protocol. Below are screenshots from the configurationFTP channel1.JPG

      FTP channel2.JPG

      FTP channel3.JPG

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi Bryan,

      But the errors details are not the FTP related error, its a database issue. Could you please put screenshot of Audit log.

      Author's profile photo Former Member
      Former Member

      Below is the screenshot of the message logPI Message Log.JPG

      Author's profile photo Former Member
      Former Member
      Blog 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

      Author's profile photo Former Member
      Former Member

      Are you using Transmission Protocol: FTP or NFS?

      Author's profile photo Former Member
      Former Member

      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

      Author's profile photo Former Member
      Former Member
      Blog 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.

      Author's profile photo Former Member
      Former Member

      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.

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Great Bryan 🙂

      Author's profile photo Former Member
      Former Member

      Great work!

      Author's profile photo Peter Wallner
      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