Skip to main content

File Transfer (FTP) Tasks

Overview

This document describes the FTP tasks available for FTP, FTPS, and SFTP operations within the CargoXplorer TMS System. These tasks provide a single interface for secure file transfers between the TMS and external systems across multiple protocols.

YAML Structure

File transfer tasks use a unified structure that automatically handles protocol-specific configurations based on the connection type specified.

Attribute Description

FileTransfer/Connect

The FileTransfer/Connect task establishes a connection to an FTP, FTPS, or SFTP server.

task: "FileTransfer/Connect@1"
name: fileTransferConnect
inputs:
host: "ftp.example.com"
protocol: "sftp" # Options: ftp, ftps, sftp
port: 22 # Optional - Auto-detected based on protocol (21=FTP, 990=FTPS, 22=SFTP)
username: "ftpuser"
authentication:
type: "password" # Options: password, privateKey (SFTP only)
password: "{{ secrets.FTP_PASSWORD }}"
privateKey: "{{ secrets.SFTP_PRIVATE_KEY }}" # SFTP only
passphrase: "{{ secrets.SFTP_KEY_PASSPHRASE }}" # SFTP only
options:
passive: true # FTP/FTPS only - Use passive mode
timeout: 30 # Connection timeout in seconds
hostKeyVerification: # SFTP only
enabled: true # Verify host key
hostKey: "ssh-rsa AAAAB3NzaC1yc2E..." # Expected host key
outputs:
- name: "connection"
mapping: "connection"

Attribute Details:

Input ParameterTypeDescriptionProtocols
hoststringServer hostname or IP addressAll
protocolstringProtocol type: ftp, ftps, sftpAll
portintegerPort number (auto-detected if not specified)All
usernamestringUsername for authenticationAll
authentication.typestringAuthentication methodAll
authentication.passwordstringPassword for authenticationAll
authentication.privateKeystringPrivate key content (PEM format)SFTP
authentication.passphrasestringPassphrase for encrypted private keySFTP
options.passivebooleanUse passive mode (default: true)FTP/FTPS
options.timeoutintegerConnection timeout in seconds (default: 30)All
options.hostKeyVerification.enabledbooleanVerify server host key (default: true)SFTP
options.hostKeyVerification.hostKeystringExpected host key for verificationSFTP

Protocol-Specific Defaults:

ProtocolDefault PortDefault Options
ftp21passive: true, secure: false
ftps990passive: true, secure: true
sftp22hostKeyVerification.enabled: true

Output:

{
"connection": {
"id": "ft-conn-123456",
"protocol": "sftp",
"host": "ftp.example.com",
"port": 22,
"connected": true,
"features": ["upload", "download", "list", "delete", "move"]
}
}

FileTransfer/Disconnect

The FileTransfer/Disconnect task closes a file transfer connection.

task: "FileTransfer/Disconnect@1"
name: fileTransferDisconnect
inputs:
connection: "{{ fileTransferConnect.connection }}"

FileTransfer/ListFiles

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

task: "FileTransfer/ListFiles@1"
name: fileTransferListFiles
inputs:
connection: "{{ fileTransferConnect.connection }}"
directory: "/incoming" # Optional - Default is root directory
pattern: "*.edi" # Optional - File pattern to match (supports wildcards)
recursive: false # Optional - List files recursively
includeDirectories: false # Optional - Include directories in results
sortBy: "lastModified" # Optional - Sort by: name, size, lastModified
sortOrder: "desc" # Optional - Sort order: asc, desc
outputs:
- name: "files"
mapping: "files"
- name: "totalSize"
mapping: "totalSize"
- name: "fileCount"
mapping: "fileCount"

Attribute Details:

Input ParameterTypeDescription
connectionobjectFile transfer connection object from FileTransfer/Connect
directorystringDirectory path to list files from
patternstringFile pattern to filter results (supports wildcards)
recursivebooleanWhether to list files recursively
includeDirectoriesbooleanInclude directories in results
sortBystringSort files by: name, size, lastModified
sortOrderstringSort order: asc, desc

Output:

{
"files": [
{
"name": "order123.edi",
"path": "/incoming/order123.edi",
"size": 1024,
"lastModified": "2023-05-15T10:30:00Z",
"permissions": "rw-r--r--",
"type": "file",
"checksum": "sha256:abc123..."
}
],
"totalSize": 3072,
"fileCount": 2
}

FileTransfer/DownloadFile

The FileTransfer/DownloadFile task downloads a file from a server.

task: "FileTransfer/DownloadFile@1"
name: fileTransferDownload
inputs:
connection: "{{ fileTransferConnect.connection }}"
remotePath: "/incoming/order123.edi"
localPath: "/tmp/downloads/order123.edi" # Optional - If not provided, file content is returned
options:
deleteAfterDownload: false # Delete remote file after download
overwrite: true # Overwrite local file if exists
preserveTimestamp: true # Preserve file timestamp (SFTP)
verifyChecksum: true # Verify file integrity
resumeTransfer: false # Resume interrupted transfers
outputs:
- name: "fileInfo"
mapping: "fileInfo"
- name: "content"
mapping: "content" # Only if localPath not provided

Attribute Details:

Input ParameterTypeDescription
connectionobjectFile transfer connection object from FileTransfer/Connect
remotePathstringPath to the file on the server
localPathstringLocal path to save the downloaded file (optional)
options.deleteAfterDownloadbooleanWhether to delete the remote file after download
options.overwritebooleanWhether to overwrite existing local file
options.preserveTimestampbooleanWhether to preserve the file's timestamp
options.verifyChecksumbooleanWhether to verify file integrity
options.resumeTransferbooleanWhether to resume interrupted transfers

Output:

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

FileTransfer/UploadFile

The FileTransfer/UploadFile task uploads a file to a server.

task: "FileTransfer/UploadFile@1"
name: fileTransferUpload
inputs:
connection: "{{ fileTransferConnect.connection }}"
localPath: "/tmp/uploads/shipment456.edi" # Either localPath or content must be provided
content: "ISA*00*..." # Either localPath or content must be provided
remotePath: "/outgoing/shipment456.edi"
options:
permissions: "0644" # File permissions (SFTP only)
createDirectories: true # Create remote directories if needed
overwrite: true # Overwrite remote file if exists
verifyChecksum: true # Verify upload integrity
resumeTransfer: false # Resume interrupted transfers
outputs:
- name: "fileInfo"
mapping: "fileInfo"

Attribute Details:

Input ParameterTypeDescription
connectionobjectFile transfer connection object from FileTransfer/Connect
localPathstringLocal path of the file to upload
contentstringFile content to upload (alternative to localPath)
remotePathstringPath to save the file on the server
options.permissionsstringFile permissions in octal format (SFTP only)
options.createDirectoriesbooleanWhether to create remote directories if needed
options.overwritebooleanWhether to overwrite existing remote file
options.verifyChecksumbooleanWhether to verify upload integrity
options.resumeTransferbooleanWhether to resume interrupted transfers

Output:

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

FileTransfer/DeleteFile

The FileTransfer/DeleteFile task deletes a file from a server.

task: "FileTransfer/DeleteFile@1"
name: fileTransferDelete
inputs:
connection: "{{ fileTransferConnect.connection }}"
remotePath: "/incoming/order123.edi"
options:
verify: true # Verify file exists before deletion
outputs:
- name: "success"
mapping: "success"
- name: "fileInfo"
mapping: "fileInfo"

Attribute Details:

Input ParameterTypeDescription
connectionobjectFile transfer connection object from FileTransfer/Connect
remotePathstringPath to the file to delete on the server
options.verifybooleanWhether to verify file exists before deletion

Output:

{
"success": true,
"fileInfo": {
"name": "order123.edi",
"path": "/incoming/order123.edi",
"deletedAt": "2023-05-15T16:30:00Z"
}
}

FileTransfer/MoveFile

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

task: "FileTransfer/MoveFile@1"
name: fileTransferMove
inputs:
connection: "{{ fileTransferConnect.connection }}"
sourcePath: "/incoming/order123.edi"
destinationPath: "/processed/order123.edi"
options:
createDirectories: true # Create destination directories if they don't exist
overwrite: true # Overwrite destination file if exists
atomic: true # Ensure atomic move operation
outputs:
- name: "success"
mapping: "success"
- name: "fileInfo"
mapping: "fileInfo"

Attribute Details:

Input ParameterTypeDescription
connectionobjectFile transfer connection object from FileTransfer/Connect
sourcePathstringPath to the source file on the server
destinationPathstringPath to move/rename the file to
options.createDirectoriesbooleanWhether to create destination directories
options.overwritebooleanWhether to overwrite existing destination file
options.atomicbooleanWhether to ensure atomic move operation

Output:

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

Examples

Multi-Protocol EDI Processing Workflow

This example demonstrates connecting to different protocols for incoming and outgoing file transfers.

# Connect to SFTP for incoming files
task: "FileTransfer/Connect@1"
name: connectIncoming
inputs:
host: "{{ partner.incomingHost }}"
protocol: "sftp"
username: "{{ partner.username }}"
authentication:
type: "privateKey"
privateKey: "{{ secrets.PARTNER_PRIVATE_KEY }}"
passphrase: "{{ secrets.KEY_PASSPHRASE }}"
options:
timeout: 60
hostKeyVerification:
enabled: true
hostKey: "{{ partner.expectedHostKey }}"
outputs:
- name: "incomingConnection"
mapping: "connection"

# Connect to FTPS for outgoing files
task: "FileTransfer/Connect@1"
name: connectOutgoing
inputs:
host: "{{ partner.outgoingHost }}"
protocol: "ftps"
port: 990
username: "{{ partner.username }}"
authentication:
type: "password"
password: "{{ secrets.PARTNER_PASSWORD }}"
options:
passive: true
timeout: 60
outputs:
- name: "outgoingConnection"
mapping: "connection"

# List and download EDI files
task: "FileTransfer/ListFiles@1"
name: listIncomingFiles
inputs:
connection: "{{ connectIncoming.incomingConnection }}"
directory: "/incoming"
pattern: "*.edi"
sortBy: "lastModified"
sortOrder: "asc"
outputs:
- name: "ediFiles"
mapping: "files"

task: "Utilities/ForEach@1"
name: processFiles
inputs:
items: "{{ listIncomingFiles.ediFiles }}"
parallel: true
maxParallel: 3
task:
task: "FileTransfer/DownloadFile@1"
name: downloadFile
inputs:
connection: "{{ connectIncoming.incomingConnection }}"
remotePath: "{{ item.path }}"
options:
deleteAfterDownload: false
verifyChecksum: true
outputs:
- name: "fileContent"
mapping: "content"

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

task: "FileTransfer/MoveFile@1"
name: moveToProcessed
inputs:
connection: "{{ connectIncoming.incomingConnection }}"
sourcePath: "{{ item.path }}"
destinationPath: "/processed/{{ item.name }}"
options:
createDirectories: true
atomic: true

# Generate and upload acknowledgment
task: "EDI/Acknowledge@1"
name: generateAck
inputs:
ediData: "{{ processFiles.parsedData }}"
acknowledgmentType: "997"
status: "A"
outputs:
- name: "ackEDI"
mapping: "ediString"

task: "FileTransfer/UploadFile@1"
name: uploadAck
inputs:
connection: "{{ connectOutgoing.outgoingConnection }}"
content: "{{ generateAck.ackEDI }}"
remotePath: "/outgoing/ACK_{{ formatDate now 'yyyyMMddHHmmss' }}.edi"
options:
createDirectories: true
verifyChecksum: true
outputs:
- name: "uploadResult"
mapping: "fileInfo"

# Disconnect from both servers
task: "FileTransfer/Disconnect@1"
name: disconnectIncoming
inputs:
connection: "{{ connectIncoming.incomingConnection }}"

task: "FileTransfer/Disconnect@1"
name: disconnectOutgoing
inputs:
connection: "{{ connectOutgoing.outgoingConnection }}"

Simple FTP File Upload

This example shows a basic file upload using FTP protocol.

task: "FileTransfer/Connect@1"
name: connectFTP
inputs:
host: "ftp.partner.com"
protocol: "ftp"
username: "{{ secrets.FTP_USERNAME }}"
authentication:
type: "password"
password: "{{ secrets.FTP_PASSWORD }}"
options:
passive: true
timeout: 30
outputs:
- name: "ftpConnection"
mapping: "connection"

task: "Document/Generate@1"
name: generateReport
inputs:
template: "shipment-report"
data: "{{ workflow.input.shipmentData }}"
format: "csv"
outputs:
- name: "reportContent"
mapping: "content"

task: "FileTransfer/UploadFile@1"
name: uploadReport
inputs:
connection: "{{ connectFTP.ftpConnection }}"
content: "{{ generateReport.reportContent }}"
remotePath: "/reports/shipment_{{ formatDate now 'yyyyMMdd' }}.csv"
options:
createDirectories: true
overwrite: true
outputs:
- name: "uploadInfo"
mapping: "fileInfo"

task: "FileTransfer/Disconnect@1"
name: disconnectFTP
inputs:
connection: "{{ connectFTP.ftpConnection }}"

SFTP with Advanced Security

This example demonstrates SFTP with enhanced security features.

task: "FileTransfer/Connect@1"
name: secureConnect
inputs:
host: "secure.partner.com"
protocol: "sftp"
port: 2222 # Custom SFTP port
username: "{{ secrets.SFTP_USERNAME }}"
authentication:
type: "privateKey"
privateKey: "{{ secrets.SFTP_PRIVATE_KEY }}"
passphrase: "{{ secrets.SFTP_KEY_PASSPHRASE }}"
options:
timeout: 45
hostKeyVerification:
enabled: true
hostKey: "{{ secrets.PARTNER_HOST_KEY }}"
outputs:
- name: "secureConnection"
mapping: "connection"

task: "FileTransfer/DownloadFile@1"
name: secureDownload
inputs:
connection: "{{ secureConnect.secureConnection }}"
remotePath: "/secure/confidential.xml"
localPath: "/tmp/secure/confidential.xml"
options:
deleteAfterDownload: true
preserveTimestamp: true
verifyChecksum: true
outputs:
- name: "downloadInfo"
mapping: "fileInfo"

task: "FileTransfer/Disconnect@1"
name: secureDisconnect
inputs:
connection: "{{ secureConnect.secureConnection }}"

Best Practices

1. Protocol Selection

  • FTP: Use only for legacy systems that don't support secure protocols

    • Limited security features
    • Passwords transmitted in plain text
    • Suitable for internal networks only
  • FTPS: Preferred for secure FTP when SFTP is not available

    • Encrypted data transmission
    • Compatible with existing FTP infrastructure
    • Supports both implicit and explicit modes
  • SFTP: Most secure option, recommended for new integrations

    • SSH-based encryption
    • Key-based authentication support
    • Host key verification
    • File permission management

2. Security Configuration

authentication:
type: "privateKey"
privateKey: "{{ secrets.SFTP_PRIVATE_KEY }}"
passphrase: "{{ secrets.KEY_PASSPHRASE }}"
options:
hostKeyVerification:
enabled: true
hostKey: "{{ secrets.EXPECTED_HOST_KEY }}"

FTPS with Strong Settings

protocol: "ftps"
port: 990 # Implicit FTPS
options:
passive: true
timeout: 30

Security Checklist

  • Never store credentials in plain text
  • Use environment variables or secure secret management
  • Rotate credentials regularly
  • Enable host key verification for SFTP
  • Use private networks or VPN for sensitive data

3. Connection Management

  • Always use FileTransfer/Disconnect to close connections
  • Set appropriate timeouts based on file sizes and network conditions
  • Use connection pooling for high-volume operations
  • Implement connection retry logic for network failures
task: "FileTransfer/Connect@1"
name: connectWithRetry
inputs:
host: "{{ partner.host }}"
protocol: "sftp"
# ... other inputs
onError:
action: "retry"
maxAttempts: 3
delaySeconds: 5
escalate: true

4. File Operations

Enable Integrity Verification

options:
verifyChecksum: true
resumeTransfer: true # For large files

Atomic Operations

options:
atomic: true # Ensures move operations are atomic

Error Handling

  • Implement proper error handling and retry logic
  • Validate file integrity after transfers
  • Use temporary directories for processing
  • Clean up temporary files after operations

5. Directory Structure

Maintain a clear directory structure on file transfer servers:

/incoming/     # New files to process
/processing/ # Files currently being processed
/processed/ # Successfully processed files
/error/ # Files that failed processing
/outgoing/ # Files to send to partners
/archive/ # Historical files for audit

6. Monitoring and Logging

  • Log all file transfer operations with timestamps
  • Monitor transfer speeds and connection reliability
  • Set up alerts for failed transfers
  • Track file processing metrics
  • Maintain audit trails for compliance
task: "Utilities/Log@1"
name: logTransfer
inputs:
level: "info"
message: "File transfer completed: {{ uploadInfo.fileInfo.name }}"
metadata:
fileSize: "{{ uploadInfo.fileInfo.size }}"
transferTime: "{{ uploadInfo.duration }}"
protocol: "{{ connection.protocol }}"

7. Performance Optimization

  • Use parallel processing for multiple file operations
  • Implement file size limits to prevent timeouts
  • Consider compression for large files
  • Use resume capabilities for interrupted transfers
  • Optimize batch sizes for list operations
task: "Utilities/ForEach@1"
name: parallelDownloads
inputs:
items: "{{ fileList.files }}"
parallel: true
maxParallel: 3 # Limit concurrent connections

Security Considerations

Authentication Security

  • Never store credentials in plain text
  • Use environment variables or secure secret management systems
  • Rotate credentials regularly according to security policies
  • Use key-based authentication for SFTP when possible
  • Implement strong passphrase policies for encrypted keys

Network Security

  • Enable host key verification for SFTP connections
  • Use FTPS instead of plain FTP for encrypted transfers
  • Implement connection timeouts to prevent hanging connections
  • Consider using VPN or private networks for sensitive data
  • Monitor for suspicious connection patterns

File Security

  • Verify file checksums for critical transfers
  • Use temporary directories for file processing
  • Clean up temporary files after processing
  • Implement file size limits to prevent abuse
  • Encrypt sensitive files before transmission

Access Control

  • Implement least privilege access principles
  • Use separate credentials for different partners
  • Regularly audit file transfer permissions
  • Monitor file access patterns
  • Implement session logging and tracking

Error Handling

Connection Errors

Common connection issues and their solutions:

  • Connection Timeout: Increase timeout values or check network connectivity
  • Authentication Failed: Verify credentials and authentication method
  • Host Key Verification Failed: Update expected host key or disable verification temporarily
  • Protocol Not Supported: Verify server protocol support and configuration

Transfer Errors

  • File Not Found: Verify file paths and permissions
  • Insufficient Space: Check available disk space on target systems
  • Permission Denied: Verify file and directory permissions
  • Transfer Interrupted: Use resume capabilities for large files

Retry Strategies

# Exponential backoff retry
onError:
action: "retry"
maxAttempts: 3
delaySeconds: [5, 10, 20]
escalate: true

# Custom error handling
onError:
action: "custom"
handler: "handleTransferError"
context:
operation: "download"
filePath: "{{ remotePath }}"

Error Logging

Maintain comprehensive error logs for troubleshooting:

task: "Utilities/Log@1"
name: logError
inputs:
level: "error"
message: "File transfer failed: {{ error.message }}"
metadata:
operation: "{{ operation }}"
filePath: "{{ filePath }}"
errorCode: "{{ error.code }}"
timestamp: "{{ now }}"

Performance Tuning

Connection Optimization

  • Use persistent connections for multiple operations
  • Implement connection pooling for high-volume scenarios
  • Set appropriate buffer sizes for network conditions
  • Monitor connection establishment times

Transfer Optimization

  • Use parallel transfers for multiple files
  • Implement compression for text-based files
  • Optimize chunk sizes for large file transfers
  • Use resume capabilities to handle interruptions

Resource Management

  • Limit concurrent connections to prevent server overload
  • Implement rate limiting for high-frequency operations
  • Monitor memory usage during large file transfers
  • Use streaming for very large files to reduce memory footprint