title: Spring SFTP Outbound Gateway: How to close the session after GET in Java Config?
body: <p>I have written a piece of code which uses Spring SFTP Outbound gateway and performs a GET operation. The whole configuration is in JAVA (no XML).
  I have made a caching session factory which allows a maximum of 10 sessions. Due to which after multiple GET request when it exceeds 10, GET request start failing.</p>
  
  <p>I read the docs and it was written to close the session after operation but i'm unable to figure out as to how to close this session in JAVA Configuration?</p>
  
  <pre><code>@org.springframework.integration.annotation.MessagingGateway
  public interface FileOperationGateway {
      @Gateway(requestChannel = "sftpChannelDownload")
      InputStream downloadFromSftp(Message&lt;Boolean&gt; message);
  
  }
  
  
  
  @Bean
  public SessionFactory&lt;LsEntry&gt; sftpSessionFactory() {
      DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
      factory.setHost(SFTP_HOST);
      factory.setPort(SFTP_PORT);
      factory.setUser(SFTP_USERNAME);
      factory.setPassword(SFTP_PASSWORD);
      factory.setAllowUnknownKeys(true);
      return new CachingSessionFactory&lt;LsEntry&gt;(factory);
  }
  
  /**
   * Bean for Caching the session 
   * 
   */
  
  @Bean
  @Autowired
  public CachingSessionFactory&lt;LsEntry&gt; cachingSessionFactory(SessionFactory&lt;LsEntry&gt; sftpSessionFactory) {
      CachingSessionFactory&lt;LsEntry&gt; cachingSessionFactory = new CachingSessionFactory&lt;&gt;(sftpSessionFactory, 10);
      cachingSessionFactory.setSessionWaitTimeout(SFTP_SESSION_TIMEOUT);
      return cachingSessionFactory;
  }
  
  /**
   * Bean for Remote File Template 
   * 
   * @return
   * @throws Exception 
   */
  
  @Bean
  @Autowired
  public RemoteFileTemplate&lt;LsEntry&gt; remoteFileTemplateDesigner(CachingSessionFactory&lt;LsEntry&gt; csf) throws Exception {
      ExpressionParser expressionParser = new SpelExpressionParser();
      Expression expression = expressionParser.parseExpression("'" + SFTP_LOCATION + "'");
      SftpRemoteFileTemplate rft = new SftpRemoteFileTemplate(csf);
      rft.setRemoteDirectoryExpression(expression);
      rft.setRemoteFileSeparator("/");
      rft.setFileNameGenerator((msg) -&gt; {
          Timestamp timestamp = new Timestamp(System.currentTimeMillis());
          Instant instant = timestamp.toInstant();
          String fileNameFromHeader = msg.getHeaders().get(FileOperationConstants.FILE_HEADER_KEY).toString();
          String newFileName;
          if (fileNameFromHeader.lastIndexOf("/") != -1) {
              newFileName = fileNameFromHeader.substring(fileNameFromHeader.lastIndexOf("/"));
          } else if (fileNameFromHeader.lastIndexOf("\\") != -1) {
              newFileName = fileNameFromHeader.substring(fileNameFromHeader.lastIndexOf("\\"));
          } else
              newFileName = fileNameFromHeader;
  
          String fileNameOnly = newFileName.substring(0, newFileName.lastIndexOf("."));
          String fileType = newFileName.substring(newFileName.lastIndexOf(".") + 1);
          return (fileNameOnly + "__" + instant.toString() + "." + fileType);
      });
      rft.afterPropertiesSet();
      return rft;
  }
  
  @Bean
  @Autowired
  @ServiceActivator(inputChannel = "sftpChannelDownload")
  public SftpOutboundGatewaySpec downloadHandler(RemoteFileTemplate&lt;LsEntry&gt; rft) {
      SftpOutboundGatewaySpec sogs =  Sftp.outboundGateway(rft, FileOperationConstants.FILE_DOWNLOAD_COMMAND,
              FileOperationConstants.FILE_DOWNLOAD_EXPRESSION);
      sogs.options(Option.STREAM);
      return sogs;
  }
  </code></pre>
  
  <blockquote>
    <p>******UPDATE:******</p>
  </blockquote>
  
  <p>I created a new class with @messageEndpoint and placed the closeable session code in it. I then called this handler from my service class (where i was consuming the stream)This worked:</p>
  
  <pre><code>    @MessageEndpoint
  public class FileOperationCloseSessionMessageHandler {
  
      @ServiceActivator(inputChannel = "sftpCloseSession")
      public void closeSession(Message&lt;Boolean&gt; msg) throws IOException {
  
          Closeable closeable = new IntegrationMessageHeaderAccessor(msg).getCloseableResource();
          if (closeable != null) {
              closeable.close();
          }
      }
  }
  </code></pre>
  
  <p>Placed this line in @MessagingGateway annotated class</p>
  
  <pre><code>@Gateway(requestChannel = "sftpCloseSession")
  void closeSession(Message&lt;InputStream&gt; msg);
  </code></pre>
  
  <p>And then called the gateway method from service class: </p>
  
  <pre><code>Message&lt;InputStream&gt; msg = msgGateway.downloadFromSftp(message);
      InputStream is = msg.getPayload();
      msgGateway.closeSession(msg);
  </code></pre>