Connects to remote FTP, FTPS, and SFTP servers. Lists files in configured remote folders with per-folder polling, performs high-throughput parallel uploads and downloads via a bounded deduplicated retry queue and connection leasing pool, supports custom JSON parameter passing on upload sink nodes, and generates upload completion events with echoed correlation payloads.
2. Technical Architecture
The FTP Client plugin handles file transport across FTP, FTPS (FTP over SSL/TLS), and SFTP (SSH File Transfer Protocol) connections using FluentFTP and SSH.NET.
Key Architectural Highlights:
1. Bounded Transfer Queue: Transfers are enqueued into an in-memory bounded channel (System.Threading.Channels.Channel<TransferItem>) with a configurable maximum capacity (default: 1,000 items). If the queue is saturated, new transfer submissions immediately return a QueueFull status to prevent blocking the visual rule gate.
2. Parallel Upload Workers: A pool of concurrent worker tasks (default: 10 parallel upload tasks) dequeues transfer jobs and executes uploads simultaneously, maximizing throughput over high-latency WAN or cloud connections.
3. Thread-Safe Transport Pool: Because underlying FTP and SFTP transport sockets are not thread-safe for concurrent operations on a single connection, ConnectionSupervisor manages an idle transport pool (ConcurrentQueue<IFtpTransport>) governed by a semaphore (parallelTasks + 2). Workers lease dedicated connections during transfers (TransportLease : IAsyncDisposable) and return healthy connections to the pool upon completion.
4. Parameter JSON & Correlation Echoing: Upload sink nodes accept an optional custom json parameter. This payload travels with the TransferItem through the queue and is echoed back in the completion event.
5. Upload Completion Events: Once an upload succeeds or fails, the adapter publishes a File Uploaded (ftp.file_uploaded) event containing file metadata, error messages (if any), and the echoed Payload / Json.
System Interaction & Exposed Catalog Routes
Catalog Routes & Node Integration
Input Event Triggers (Input Nodes):
ftp.file_uploaded (File Uploaded) - Real-time event emitted whenever a file upload completes. Contains success status, transfer metrics, and echoed sink payload.
ftp.file_downloaded - Emitted when a remote file download finishes.
ftp.remote_directory_listed - Emitted on directory listing completion.
ftp.transfer_completed - Transfer success notification.
Executable Actions (Action Nodes):
ftp.upload_file (ftp:upload) - Uploads a local file to remote server with optional correlation JSON parameter.
ftp.download_file (ftp:download) - Downloads a file from remote server.
Real-time event triggered immediately upon completion of an upload operation. Echoes back the custom json parameter or payload supplied at the upload sink node for correlation.
File Arrived EventFile Arrived Event
↳
Name (String)
Extension (String)
Size (Int32)
Directory (String)
FullPath (String)
LastWriteTime (DateTime)
Real-time event triggered whenever a new or modified file is detected on the remote server by the directory poller.
Data Source
The Data Source node queries directory file lists from remote FTP/SFTP servers.
Human-Readable Collection Name
Data Type
Exposed Fields & Data Types
Description
Remote Directory FilesJson` (`collection`)
↳
Name (String)
Extension (String)
Size (Int32)
Directory (String)
FullPath (String)
LastWriteTime (DateTime)
List of file entry objects in monitored remote directory.
Output Target
The Output Target node acts as an action sink node to upload or download files across FTP/SFTP servers.
Target Name
Data Type
Associated Parameters
Parameter Data Type
Required
Description
Upload File (ftp:upload) Json
↳
Local File Path (path)
String
True
Path to local source file on disk.
↳
Remote Folder (folder)
String
True
Target directory on remote FTP/SFTP server.
↳
Remote File Name (remoteName)
String
False
Optional destination file name on remote server.
↳
Result Storage Point (resultTag)
String
False
Storage tag to record transfer status result in Internal Storage.
↳
Parameter JSON (json)
Json
False
Optional custom JSON string or object payload passed with the upload request. Preserved through the queue and echoed back in the File Uploaded event upon completion.
Download File (ftp:download) Json
↳
Remote File Path (remotePath)
String
True
Remote file path on server.
↳
Local Folder (localFolder)
String
True
Destination directory path on local disk.
↳
Local File Name (localName)
String
False
Optional local destination file name.
↳
Result Storage Point (resultTag)
String
False
Storage tag to record transfer status result in Internal Storage.
5. Usage Examples
Scenario A: Avigilon Media Downloaded Event Uploads Snapshot Image to Remote SFTP Backup Server
Workflow Overview:
When Avigilon ACC downloads a high-resolution snapshot image (avigilon.media_downloaded with FilePath), Uniflow intercepts the download completion event and automatically uploads (ftp.upload_file) the image to an offsite secure SFTP backup server in directory /backups/snapshots/.
When a remote SFTP directory poller detects a new CSV config file (File Arrived Event on /exports/ directory), Uniflow issues a Download File action (ftp.download_file) to save the file locally into C:\Uniflow\Staging\, followed by a Database Link query execution to process the CSV rows.
Rule Node Configuration:
1. Event Input Node: FTP Client Listener
Filter Event: File Arrived Event
Exposed Fields: FullPath (String), Extension (String), Name (String)
2. Logic Condition Node: Equal
Expression: Extension == ".csv"
3. Output Target Node A: FTP Client Action
Action Target: Download File (ftp.download_file)
Remote File Path: FullPath
Local Folder: C:\Uniflow\Staging\
4. Output Target Node B: Database Link Action
Action Target: Execute Query
Query: BULK INSERT Inventory FROM 'C:\Uniflow\Staging\${Name}' WITH (FORMAT='CSV')
A high-frequency rule pipeline generates alarm reports across dozens of monitored points. Each alarm report is immediately dispatched to Upload File (ftp:upload) along with a correlation payload containing the originating rule ID and incident context:
The FTP Client plugin enqueues the uploads into its bounded queue (capacity 1,000) and dispatches them across 10 concurrent upload tasks using pooled connections. When each upload completes, the File Uploaded event fires, echoing back the original Payload JSON, which is then routed to a WebHook node to notify an external dispatch center.