-2

I'm trying to read a couple of files from SecureFTP client for run a daily report task:

The file contents from both the files(.bck file format) looks like this in each line

|00000001|FirstName|LastName|Active|0001|00000000|
|00000002|FirstName|LastName|Incctive|0002|00000001|
|00000003|FirstName|LastName|Active|0003|00020002|

So far, I have successfully made the connection and able to read the file names but unable to read the file contents:

  import net.schmizz.sshj.SSHClient;
  import net.schmizz.sshj.sftp.SFTPClient;
  import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
  import net.schmizz.sshj.sftp.RemoteFile.RemoteFileInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.time.LocalDate;
  import java.time.format.DateTimeFormatter;
  import java.util.ArrayList;
  import java.util.List;
  import org.apache.commons.io.IOUtils;

  SSHClient ssh = new SSHClient();
  ssh.addHostKeyVerifier(new PromiscuousVerifier());

  try {
    ssh.connect("ServerName");
    ssh.authPassword("username", "password");

    SFTPClient sftp = ssh.newSFTPClient();
    List fileContentsList = new ArrayList();

    try {
      List files = sftp.ls("/");
      LocalDate yesterday = LocalDate.now().minusDays(1);
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
      boolean usFileFound = false;
      boolean caFileFound = false;

      for (file : files) {
        String fileName = file.getName();

        if (!file.isDirectory()) {
          if (fileName.contains("SAPHR_POS_CAEEMD_") && fileName.contains(yesterday.format(formatter)) && !caFileFound) {
            RemoteFile remoteFile = sftp.open(fileName); // Obtain the RemoteFile handle
            InputStream inputStream = new RemoteFileInputStream(remoteFile); // Get the input stream
            //List lines = Arrays.asList(fileContents.split("\n"));
            String fileContents = IOUtils.toString(inputStream, "UTF-8"); // Read contents as a string
            fileContentsList.add(fileContents); // Add the contents as string to the list
            caFileFound = true;
            remoteFile.close();

          } else if (fileName.contains("SAPHR_POS_USEEMD_") && fileName.contains(yesterday.format(formatter)) && !usFileFound) {
            RemoteFile remoteFile = sftp.open(fileName); 
            InputStream inputStream = new RemoteFileInputStream(remoteFile);
            String fileContents = IOUtils.toString(inputStream, "UTF-8");
            fileContentsList.add(fileContents);
            usFileFound = true;
            remoteFile.close();
          }
          if (caFileFound && usFileFound) {
            break; // Stop after both files found
          }
        }
      }
    } finally {
      sftp.close();
    }

    String result = String.join("\n", fileContentsList);
    return result;
  } finally {
    try {
      ssh.disconnect();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

The output from current code:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE List PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<List>
  <String>SAPHR_POS_CAEEMD_20230722.txt1690068889231.bck</String>
  <String>SAPHR_POS_USEEMD_20230722.txt1690068894774.bck</String>
</List>

The error received while trying to perform the commented lines in above code:

Exception running rule: BeanShell script error: bsh.EvalError: Sourced file: inline evaluation of: 
Author: user007 Date: 16-07-2023     Details: ********* . . . '' : Typed variable declaration : Error in method invocation: Method getInputStream(java.lang.String) not found in class'net.schmizz.sshj.sftp.SFTPClient' :
at Line: 48 : in file: inline evaluation of:
``   /*********** Author: user007  Date: 16-07-2023  Details: ********* . . . '' : sftp .getInputStream ( fileName )   BSF info: usersReport
at line: 0 column: columnNo
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
D C
  • 41
  • 6
  • I don't see where this code outputs anything at all, let alone this XML. – user207421 Jul 23 '23 at 06:56
  • @user207421 this line --> return fileContentsList; – D C Jul 23 '23 at 07:05
  • 2
    1) You have mangled your source code. `&&` is not valid Java. 2) `return fileContentsList;` is not outputting XML. It is returning a list that apparently contains file names. – Stephen C Jul 23 '23 at 07:35
  • @StephenC updated the code, its not mangled its just the format in my app on how to represent special characters, its a bean shell script --> https://beanshell.github.io/manual/contents.html And yes, its returning the filenames in a List, but what I was looking is a way to output the file contents instead of file names – D C Jul 23 '23 at 07:42
  • What's with the XML? Ordinarily nothing to do with sftp/ssh – g00se Jul 23 '23 at 08:18
  • @g00se yes xml has nothing to do with it, the out was a list of filenames, I was looking on how to get the file contents – D C Jul 23 '23 at 11:48
  • 2
    @DC - Advice: if something has nothing to do with the task at hand **don't put it in the question**. It only serves to **confuse** people. Likewise, with tags. AFAIK, `[sailpoint]` is not relevant to your question at all. – Stephen C Jul 23 '23 at 11:51
  • 1
    If you want to get files, you should be using [this](https://www.javadoc.io/static/com.hierynomus/sshj/0.23.0/net/schmizz/sshj/sftp/SFTPClient.html#get-java.lang.String-java.lang.String-) – g00se Jul 23 '23 at 13:22
  • @DC `return fileContentsList` does not constitute outputting anything, let alone XML. – user207421 Jul 24 '23 at 05:31

1 Answers1

1

I think that the problem is that you are using the APIs incorrectly.

If you look at the examples for SFTPClient, they don't use a method called getretrieveFileStream. In fact, there isn't a method in the API whose name remotely resembles that. Calling non-existent methods is never going to work.

I recommend that you look at the examples for yourself and see if they do what you want. And look at the javadocs for the APIs. For example:

I suspect the pattern for extracting the contents of a file will be something like this:

  1. Obtain an SFTPClient.
  2. Call open on the client to obtain a RemoteFile handle for the file you want to read.
  3. Using that handle as the outer class context, invoke the RemoteFileInputStream no-args constructor to get an input stream.
  4. Read from the input stream in the normal way
  5. Close the stream and the handle
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Solved it found the right method, thanks for your inputs :) I have updated the code – D C Jul 23 '23 at 17:46