Categories: Uncategorised

Spring Integration – Sending files over SFTP

Spring Integration is a powerful extension of the Spring Framework designed to support the implementation of enterprise integration patterns in a Spring-based application. It provides a set of components and APIs for building messaging solutions and integrating disparate systems within an application.

At its core, Spring Integration leverages the concept of message-driven architectures, where components communicate by sending and receiving messages through channels. It enables the implementation of complex integration scenarios by providing support for various communication protocols, message routing, transformation, and mediation.

Key components of Spring Integration include:

  1. Message: The fundamental unit of communication in Spring Integration, containing data and headers.
  2. Channel: Acts as a conduit for messages to flow between components. Channels can be direct, point-to-point, publish-subscribe, etc.
  3. Message Endpoint: Represents the integration logic that consumes or produces messages from or to the messaging system.
  4. Message Handler: Components responsible for processing incoming messages.
  5. Message Source: Represents an input channel adapter that generates messages.
  6. Message Transformer: Converts or transforms messages from one format to another.
  7. Message Router: Determines the path of the message based on predefined criteria.
  8. Message Filter: Evaluates messages and decides whether to allow them to pass through or not.
  9. Service Activator: Invokes a service or method with the message payload.

Lets see the steps for sending files over SFTP using Spring Integration.

i) Include the required below dependency

<dependency>
  <groupId>org.springframework.integration</groupId>
  <artifactId>spring-integration-sftp</artifactId>
</dependency>

ii) Configuration to set up integration flow

package com.example.springintegrationsftp.config;

import java.io.File;

import org.apache.sshd.sftp.client.SftpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.file.FileNameGenerator;
import org.springframework.integration.file.remote.session.CachingSessionFactory;
import org.springframework.integration.file.remote.session.SessionFactory;
import org.springframework.integration.sftp.outbound.SftpMessageHandler;
import org.springframework.integration.sftp.session.DefaultSftpSessionFactory;
import org.springframework.integration.sftp.session.SftpRemoteFileTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;

@Configuration
@EnableIntegration
public class SftpConfig {
 
 @Value("${sftp.host}")
 private  String host;
 @Value("${sftp.user}")
 private String user;
 @Value("${sftp.password}")
 private String password;

    @Bean
    public SessionFactory<SftpClient.DirEntry> sftpSessionFactory() {
        DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
        factory.setHost(host);
        factory.setPort(22);
        factory.setUser(user);
        factory.setPassword(password);
        factory.setAllowUnknownKeys(true);
        return new CachingSessionFactory<>(factory);
    }

    @Bean
    @ServiceActivator(inputChannel = "toSftpChannel")
    public MessageHandler handler() {
        SftpMessageHandler handler = new SftpMessageHandler(sftpSessionFactory());
        handler.setRemoteDirectoryExpression(new LiteralExpression("/"));
        handler.setLoggingEnabled(true);
        handler.setFileNameGenerator(new FileNameGenerator() {
            @Override
            public String generateFileName(Message<?> message) {
                if (message.getPayload() instanceof File) {
                    return ((File) message.getPayload()).getName();
                } else throw new IllegalArgumentException("File expected in message payload");
            }
        });
        return handler;
    }

    @MessagingGateway(asyncExecutor = "sftpAsync")
    public interface CustomGateway {
        @Gateway(requestChannel = "toSftpChannel")
        void sendToSftp(File file);
    }
    
    @Bean
    public AsyncTaskExecutor sftpAsync() {
     SimpleAsyncTaskExecutor simpleAsyncTaskExecutor = new SimpleAsyncTaskExecutor();
     simpleAsyncTaskExecutor.setThreadNamePrefix("sftp-exec-");
     return simpleAsyncTaskExecutor;
    }
}

iii) Define Service to invoke the file transfer

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.stereotype.Service;
import com.example.springintegrationsftp.config.SftpConfig;

@Service
public class SftpService {

 @Autowired
 SftpConfig.CustomGateway sftpGateway;

    public void uploadFileToSftp() {     
   
     sftpGateway.sendToSftp(new FileSystemResource("D://sftp.txt").getFile());
     
    }
}

iv) Define REST API to invoke the file transfer

@RestController
public class SftpController {
 
 @Autowired
 SftpService service;

 @GetMapping("/sendFile")
 public void sendFile() {
 
  service.uploadFileToSftp();
 }
}

In the internet found this free SFTP server(https://sftpcloud.io/tools/free-sftp-server) which we will be using to test sending file over SFTP.

Now we can hit our endpoint http://localhost:8080/sendFile to initiate the SFTP of file.

After the API is invoked could see the file in the SFTP server using the any SFTP client like winscp.

For complete source code: https://github.com/MMahendravarman/Springboot_Examples

mahendravarman.m@gmail.com

Recent Posts

Spring Webflux Functional Endpoint – File Upload

In this blog using the Spring WebFlux module, we are going to leverage the functional…

9 months ago

Serverless Functions with Spring Cloud Function, AWS Lambda

Spring Cloud Function is a project within the Spring ecosystem that allows developers to build…

9 months ago

Spring Boot + RabbitMQ – Decoupling Microservices Communication

RabbitMQ is an open-source message broker software that implements the Advanced Message Queuing Protocol (AMQP).…

9 months ago

Spring Cloud Config Client

The Spring Cloud Config Client is a component of the Spring Cloud framework that enables…

10 months ago

Handling CSV in Python

In Python, handling CSV (Comma Separated Values) files is easy using the built-in csv module.…

10 months ago

Spring Cloud Config Server – JDBC Backend

Spring Cloud Config Server provides a centralized location for managing and serving configuration information to…

10 months ago