Skip to main content

FTP and SFTP Tasks

Overview

This document describes the tasks available for FTP (File Transfer Protocol) and SFTP (SSH File Transfer Protocol) operations within the CargoXplorer TMS System. These tasks enable secure file transfers between the TMS and external systems.

YAML Structure

FTP and SFTP tasks follow a consistent structure that allows for flexible configuration of file transfer operations.

Attribute Description

FTP/Connect

The FTP/Connect task establishes a connection to an FTP server.

task: "FTP/Connect@1"
name: ftpConnect
inputs:
host: "ftp.example.com"
port: 21 # Optional - Default is 21
username: "ftpuser"
password: "{{ secrets.FTP_PASSWORD }}"
passive: true # Optional - Use passive mode
secure: false # Optional - Use explicit FTPS (FTP over TLS)
timeout: 30 # Optional - Connection timeout in seconds
outputs:
- name: "connection"
mapping: "connection"

Attribute Details:

Input ParameterDescription
hostFTP server hostname or IP address
portPort number for the FTP server
usernameUsername for authentication
passwordPassword for authentication
passiveWhether to use passive mode
secureWhether to use FTPS (FTP over TLS)
timeoutConnection timeout in seconds

Output:

{
"connection": {
"id": "ftp-conn-123456",
"host": "ftp.example.com",
"connected": true
}
}

FTP/Disconnect

The FTP/Disconnect task closes an FTP connection.

task: "FTP/Disconnect@1"
name: ftpDisconnect
inputs:
connection: "{{ ftpConnect.connection }}"

FTP/ListFiles

The FTP/ListFiles task retrieves a list of files from an FTP server directory.

task: "FTP/ListFiles@1"
name: ftpListFiles
inputs:
connection: "{{ ftpConnect.connection }}"
directory: "/incoming" # Optional - Default is root directory
pattern: "*.edi" # Optional - File pattern to match
recursive: false # Optional - List files recursively
outputs:
- name: "files"
mapping: "files"

Attribute Details:

Input ParameterDescription
connectionFTP connection object from FTP/Connect
directoryDirectory path to list files from
patternFile pattern to filter results
recursiveWhether to list files recursively

Output:

{
"files": [
{
"name": "order123.edi",
"path": "/incoming/order123.edi",
"size": 1024,
"lastModified": "2023-05-15T10:30:00Z",
"type": "file"
},
{
"name": "shipment456.edi",
"path": "/incoming/shipment456.edi",
"size": 2048,
"lastModified": "2023-05-15T11:45:00Z",
"type": "file"
}
]
}

FTP/DownloadFile

The FTP/DownloadFile task downloads a file from an FTP server.

task: "FTP/DownloadFile@1"
name: ftpDownloadFile
inputs:
connection: "{{ ftpConnect.connection }}"
remotePath: "/incoming/order123.edi"
localPath: "/tmp/downloads/order123.edi" # Optional - If not provided, file content is returned
deleteAfterDownload: false # Optional - Delete remote file after download
overwrite: true # Optional - Overwrite local file if exists
outputs:
- name: "fileInfo"
mapping: "fileInfo"
- name: "content"
mapping: "content" # Only if localPath is not provided

Attribute Details:

Input ParameterDescription
connectionFTP connection object from FTP/Connect
remotePathPath to the file on the FTP server
localPathLocal path to save the downloaded file
deleteAfterDownloadWhether to delete the remote file after download
overwriteWhether to overwrite existing local file

Output:

{
"fileInfo": {
"name": "order123.edi",
"path": "/tmp/downloads/order123.edi",
"size": 1024,
"lastModified": "2023-05-15T10:30:00Z"
},
"content": "ISA*00* *00* *ZZ*ABCDEFGH *ZZ*123456789 *210101*1030*U*00401*000000001*0*P*>\n..."
}

FTP/UploadFile

The FTP/UploadFile task uploads a file to an FTP server.

task: "FTP/UploadFile@1"
name: ftpUploadFile
inputs:
connection: "{{ ftpConnect.connection }}"
localPath: "/tmp/uploads/shipment456.edi" # Either localPath or content must be provided
content: "ISA*00* *00* *ZZ*ABCDEFGH *ZZ*123456789 *210101*1030*U*00401*000000001*0*P*>\n..." # Either localPath or content must be provided
remotePath: "/outgoing/shipment456.edi"
createDirectories: true # Optional - Create remote directories if they don't exist
overwrite: true # Optional - Overwrite remote file if exists
outputs:
- name: "fileInfo"
mapping: "fileInfo"

Attribute Details:

Input ParameterDescription
connectionFTP connection object from FTP/Connect
localPathLocal path of the file to upload
contentFile content to upload (alternative to localPath)
remotePathPath to save the file on the FTP server
createDirectoriesWhether to create remote directories if needed
overwriteWhether to overwrite existing remote file

Output:

{
"fileInfo": {
"name": "shipment456.edi",
"path": "/outgoing/shipment456.edi",
"size": 2048,
"uploaded": true,
"timestamp": "2023-05-15T14:30:00Z"
}
}

FTP/DeleteFile

The FTP/DeleteFile task deletes a file from an FTP server.

task: "FTP/DeleteFile@1"
name: ftpDeleteFile
inputs:
connection: "{{ ftpConnect.connection }}"
remotePath: "/incoming/order123.edi"
outputs:
- name: "success"
mapping: "success"

Attribute Details:

Input ParameterDescription
connectionFTP connection object from FTP/Connect
remotePathPath to the file to delete on the FTP server

Output:

{
"success": true
}

FTP/MoveFile

The FTP/MoveFile task moves or renames a file on an FTP server.

task: "FTP/MoveFile@1"
name: ftpMoveFile
inputs:
connection: "{{ ftpConnect.connection }}"
sourcePath: "/incoming/order123.edi"
destinationPath: "/processed/order123.edi"
createDirectories: true # Optional - Create destination directories if they don't exist
overwrite: true # Optional - Overwrite destination file if exists
outputs:
- name: "success"
mapping: "success"
- name: "fileInfo"
mapping: "fileInfo"

Attribute Details:

Input ParameterDescription
connectionFTP connection object from FTP/Connect
sourcePathPath to the source file on the FTP server
destinationPathPath to move/rename the file to
createDirectoriesWhether to create destination directories
overwriteWhether to overwrite existing destination file

Output:

{
"success": true,
"fileInfo": {
"name": "order123.edi",
"path": "/processed/order123.edi",
"size": 1024,
"lastModified": "2023-05-15T15:30:00Z"
}
}

SFTP/Connect

The SFTP/Connect task establishes a connection to an SFTP server.

task: "SFTP/Connect@1"
name: sftpConnect
inputs:
host: "sftp.example.com"
port: 22 # Optional - Default is 22
username: "sftpuser"
authentication:
type: "password" # Options: password, privateKey
password: "{{ secrets.SFTP_PASSWORD }}" # Required if type is password
privateKey: "{{ secrets.SFTP_PRIVATE_KEY }}" # Required if type is privateKey
passphrase: "{{ secrets.SFTP_KEY_PASSPHRASE }}" # Optional - For encrypted private keys
timeout: 30 # Optional - Connection timeout in seconds
hostKeyVerification:
enabled: true # Optional - Verify host key
hostKey: "ssh-rsa AAAAB3NzaC1yc2E..." # Optional - Expected host key
outputs:
- name: "connection"
mapping: "connection"

Attribute Details:

Input ParameterDescription
hostSFTP server hostname or IP address
portPort number for the SFTP server
usernameUsername for authentication
authentication.typeAuthentication method (password or privateKey)
authentication.passwordPassword for password authentication
authentication.privateKeyPrivate key for key-based authentication
authentication.passphrasePassphrase for encrypted private key
timeoutConnection timeout in seconds
hostKeyVerification.enabledWhether to verify the server's host key
hostKeyVerification.hostKeyExpected host key for verification

Output:

{
"connection": {
"id": "sftp-conn-123456",
"host": "sftp.example.com",
"connected": true
}
}

SFTP/Disconnect

The SFTP/Disconnect task closes an SFTP connection.

task: "SFTP/Disconnect@1"
name: sftpDisconnect
inputs:
connection: "{{ sftpConnect.connection }}"

SFTP/ListFiles

The SFTP/ListFiles task retrieves a list of files from an SFTP server directory.

task: "SFTP/ListFiles@1"
name: sftpListFiles
inputs:
connection: "{{ sftpConnect.connection }}"
directory: "/incoming" # Optional - Default is root directory
pattern: "*.edi" # Optional - File pattern to match
recursive: false # Optional - List files recursively
outputs:
- name: "files"
mapping: "files"

Attribute Details:

Input ParameterDescription
connectionSFTP connection object from SFTP/Connect
directoryDirectory path to list files from
patternFile pattern to filter results
recursiveWhether to list files recursively

Output:

{
"files": [
{
"name": "order123.edi",
"path": "/incoming/order123.edi",
"size": 1024,
"lastModified": "2023-05-15T10:30:00Z",
"permissions": "rw-r--r--",
"type": "file"
},
{
"name": "shipment456.edi",
"path": "/incoming/shipment456.edi",
"size": 2048,
"lastModified": "2023-05-15T11:45:00Z",
"permissions": "rw-r--r--",
"type": "file"
}
]
}

SFTP/DownloadFile

The SFTP/DownloadFile task downloads a file from an SFTP server.

task: "SFTP/DownloadFile@1"
name: sftpDownloadFile
inputs:
connection: "{{ sftpConnect.connection }}"
remotePath: "/incoming/order123.edi"
localPath: "/tmp/downloads/order123.edi" # Optional - If not provided, file content is returned
deleteAfterDownload: false # Optional - Delete remote file after download
overwrite: true # Optional - Overwrite local file if exists
preserveTimestamp: true # Optional - Preserve file timestamp
outputs:
- name: "fileInfo"
mapping: "fileInfo"
- name: "content"
mapping: "content" # Only if localPath is not provided

Attribute Details:

Input ParameterDescription
connectionSFTP connection object from SFTP/Connect
remotePathPath to the file on the SFTP server
localPathLocal path to save the downloaded file
deleteAfterDownloadWhether to delete the remote file after download
overwriteWhether to overwrite existing local file
preserveTimestampWhether to preserve the file's timestamp

Output:

{
"fileInfo": {
"name": "order123.edi",
"path": "/tmp/downloads/order123.edi",
"size": 1024,
"lastModified": "2023-05-15T10:30:00Z",
"permissions": "rw-r--r--"
},
"content": "ISA*00* *00* *ZZ*ABCDEFGH *ZZ*123456789 *210101*1030*U*00401*000000001*0*P*>\n..."
}

SFTP/UploadFile

The SFTP/UploadFile task uploads a file to an SFTP server.

task: "SFTP/UploadFile@1"
name: sftpUploadFile
inputs:
connection: "{{ sftpConnect.connection }}"
localPath: "/tmp/uploads/shipment456.edi" # Either localPath or content must be provided
content: "ISA*00* *00* *ZZ*ABCDEFGH *ZZ*123456789 *210101*1030*U*00401*000000001*0*P*>\n..." # Either localPath or content must be provided
remotePath: "/outgoing/shipment456.edi"
permissions: "0644" # Optional - Set file permissions (octal)
createDirectories: true # Optional - Create remote directories if they don't exist
overwrite: true # Optional - Overwrite remote file if exists
outputs:
- name: "fileInfo"
mapping: "fileInfo"

Attribute Details:

Input ParameterDescription
connectionSFTP connection object from SFTP/Connect
localPathLocal path of the file to upload
contentFile content to upload (alternative to localPath)
remotePathPath to save the file on the SFTP server
permissionsFile permissions in octal format
createDirectoriesWhether to create remote directories if needed
overwriteWhether to overwrite existing remote file

Output:

{
"fileInfo": {
"name": "shipment456.edi",
"path": "/outgoing/shipment456.edi",
"size": 2048,
"uploaded": true,
"permissions": "rw-r--r--",
"timestamp": "2023-05-15T14:30:00Z"
}
}

SFTP/DeleteFile

The SFTP/DeleteFile task deletes a file from an SFTP server.

task: "SFTP/DeleteFile@1"
name: sftpDeleteFile
inputs:
connection: "{{ sftpConnect.connection }}"
remotePath: "/incoming/order123.edi"
outputs:
- name: "success"
mapping: "success"

Attribute Details:

Input ParameterDescription
connectionSFTP connection object from SFTP/Connect
remotePathPath to the file to delete on the SFTP server

Output:

{
"success": true
}

SFTP/MoveFile

The SFTP/MoveFile task moves or renames a file on an SFTP server.

task: "SFTP/MoveFile@1"
name: sftpMoveFile
inputs:
connection: "{{ sftpConnect.connection }}"
sourcePath: "/incoming/order123.edi"
destinationPath: "/processed/order123.edi"
createDirectories: true # Optional - Create destination directories if they don't exist
overwrite: true # Optional - Overwrite destination file if exists
outputs:
- name: "success"
mapping: "success"
- name: "fileInfo"
mapping: "fileInfo"

Attribute Details:

Input ParameterDescription
connectionSFTP connection object from SFTP/Connect
sourcePathPath to the source file on the SFTP server
destinationPathPath to move/rename the file to
createDirectoriesWhether to create destination directories
overwriteWhether to overwrite existing destination file

Output:

{
"success": true,
"fileInfo": {
"name": "order123.edi",
"path": "/processed/order123.edi",
"size": 1024,
"lastModified": "2023-05-15T15:30:00Z",
"permissions": "rw-r--r--"
}
}

Examples

Downloading EDI Files from SFTP Server

task: "SFTP/Connect@1"
name: connectToPartnerSFTP
inputs:
host: "{{ partner.sftpHost }}"
port: 22
username: "{{ partner.sftpUsername }}"
authentication:
type: "password"
password: "{{ secrets.PARTNER_SFTP_PASSWORD }}"
timeout: 60
outputs:
- name: "sftpConnection"
mapping: "connection"

task: "SFTP/ListFiles@1"
name: listEDIFiles
inputs:
connection: "{{ connectToPartnerSFTP.sftpConnection }}"
directory: "/incoming"
pattern: "*.edi"
outputs:
- name: "ediFiles"
mapping: "files"

task: "Utilities/ForEach@1"
name: processEDIFiles
inputs:
items: "{{ listEDIFiles.ediFiles }}"
parallel: true
maxParallel: 5
task:
task: "SFTP/DownloadFile@1"
name: downloadEDIFile
inputs:
connection: "{{ connectToPartnerSFTP.sftpConnection }}"
remotePath: "{{ item.path }}"
deleteAfterDownload: true
outputs:
- name: "fileContent"
mapping: "content"

task: "EDI/Parse@1"
name: parseEDIFile
inputs:
ediData: "{{ downloadEDIFile.fileContent }}"
validateSchema: true
outputs:
- name: "parsedData"
mapping: "result"
- name: "transactionType"
mapping: "transactionType"

task: "SFTP/Disconnect@1"
name: disconnectFromSFTP
inputs:
connection: "{{ connectToPartnerSFTP.sftpConnection }}"

Uploading EDI Acknowledgments to FTP Server

task: "FTP/Connect@1"
name: connectToPartnerFTP
inputs:
host: "{{ partner.ftpHost }}"
port: 21
username: "{{ partner.ftpUsername }}"
password: "{{ secrets.PARTNER_FTP_PASSWORD }}"
passive: true
secure: true
outputs:
- name: "ftpConnection"
mapping: "connection"

task: "EDI/Acknowledge@1"
name: generateAcknowledgment
inputs:
ediData: "{{ workflow.input.originalEDI }}"
acknowledgmentType: "997"
status: "A"
outputs:
- name: "acknowledgmentEDI"
mapping: "ediString"

task: "FTP/UploadFile@1"
name: uploadAcknowledgment
inputs:
connection: "{{ connectToPartnerFTP.ftpConnection }}"
content: "{{ generateAcknowledgment.acknowledgmentEDI }}"
remotePath: "/outgoing/ACK_{{ formatDate now 'YYYYMMDDHHmmss' }}.edi"
createDirectories: true
outputs:
- name: "uploadInfo"
mapping: "fileInfo"

task: "FTP/Disconnect@1"
name: disconnectFromFTP
inputs:
connection: "{{ connectToPartnerFTP.ftpConnection }}"

Best Practices

  1. Secure Credentials: Always use environment variables or secrets management for storing credentials.

  2. Connection Management: Always disconnect from FTP/SFTP servers after operations are complete.

  3. Error Handling: Implement proper error handling for network issues and file operation failures.

  4. File Naming: Use consistent file naming conventions with timestamps to avoid conflicts.

  5. Directory Structure: Maintain a clear directory structure on FTP/SFTP servers (e.g., /incoming, /outgoing, /processed, /errors).

  6. Logging: Log all file transfer operations for audit and troubleshooting purposes.

  7. Timeout Configuration: Set appropriate timeouts based on expected file sizes and network conditions.

  8. Host Key Verification: For SFTP, always verify host keys in production environments to prevent man-in-the-middle attacks.