6.3 Salesforce Connector, JMS Messaging & File/FTP Connectors
Key Takeaways
- The Salesforce Connector supports OAuth 2.0 (JWT Bearer / Web Flow) and Basic Authentication, providing operations for SOQL Query (with automatic cursor pagination), Create, Update, and Upsert using an external ID field.
- The Salesforce Replay Channel Listener consumes Change Data Capture (CDC) and Platform Events with replay options: -1 (only new events from subscription), -2 (all retained events in the 24-72 hour window), or a specific replayId stored in Object Store.
- The JMS Connector enables enterprise asynchronous messaging via Queues (point-to-point, single-consumer) and Topics (publish-subscribe, multi-consumer broadcast) with Immediate, Auto (post-flow ACK), and Manual acknowledgement modes.
- The File and SFTP Connectors support polling listeners (On New or Updated File) with modified-timestamp watermarking, directory traversal, partial-file write locking, and non-destructive post-processing actions (Move, Rename, Delete).
- Mule 4's repeatable streaming engine automatically manages large payloads across Salesforce, JMS, and File connectors, buffering small streams in memory and transparently spilling to disk when memory thresholds (default 512 KB) are exceeded.
Salesforce Connector, JMS Messaging & File/FTP Connectors
Enterprise application networks require seamless communication across diverse protocols: enterprise SaaS platforms (Salesforce CRM), asynchronous message brokers (JMS / ActiveMQ / IBM MQ), and legacy batch file storage (Local File Systems, FTP, and SFTP). Mule 4 provides purpose-built connectors for each of these technologies, featuring unified streaming semantics, non-blocking execution, and built-in reliability patterns.
1. Salesforce Connector: Operations & Authentication
The Salesforce Connector (mule-salesforce-connector) enables comprehensive integration with Salesforce Sales Cloud, Service Cloud, and custom Salesforce platforms.
+-----------------------------------------------------------------------------------------+
| SALESFORCE CONNECTOR ARCHITECTURE |
| |
| +---------------------------------------------------------------------------------+ |
| | Mule Application Flow | |
| | - <salesforce:query> - <salesforce:upsert> | |
| | - <salesforce:create> - <salesforce:replay-channel-listener> | |
| +---------------------------------------------------------------------------------+ |
| | |
| +----------------------+----------------------+ |
| v v |
| [Synchronous REST/SOAP APIs] [Streaming CometD / PubSub] |
| - SOQL Queries (Auto-Paged 2000 records) - Change Data Capture (CDC) |
| - CRUD Operations (SaveResult / UpsertResult) - Platform Events / PushTopics |
| | | |
| +----------------------+----------------------+ |
| v |
| +---------------------------------------------------------------------------------+ |
| | Salesforce Core Platform (Force.com Engine) | |
| +---------------------------------------------------------------------------------+ |
+-----------------------------------------------------------------------------------------+
Authentication Configurations:
- OAuth 2.0 JWT Bearer (
<salesforce:jwt-connection>): Recommended for automated server-to-server production integrations. Uses an X.509 private key certificate, Connected App consumer key, and service account username without requiring human interactive login. - Basic Username / Password (
<salesforce:basic-connection>): Requiresusername,password, and the user's SalesforcesecurityToken(appended to password if not configured in a separate field). - OAuth 2.0 Web Flow (
<salesforce:oauth-user-pass-connection>/<salesforce:oauth-authorization-code-connection>): Used when authorization requires interactive end-user consent.
Core Salesforce Operations Matrix
| Operation | XML Element | Description | Return Type |
|---|---|---|---|
| Query | <salesforce:query> | Executes SOQL query. Automatically handles 2,000-record query locator pagination. | Array<Object> (CursorProvider streaming list of Salesforce sObjects) |
| Create | <salesforce:create> | Inserts new sObjects (Single or Collection). | Array<SaveResult> containing id, success (boolean), errors |
| Update | <salesforce:update> | Modifies existing sObjects matching standard Id. | Array<SaveResult> containing id, success (boolean), errors |
| Upsert | <salesforce:upsert> | Creates or updates records based on a custom External ID field. | Array<UpsertResult> containing id, success, created (boolean), errors |
| Delete | <salesforce:delete> | Deletes records by Salesforce Id. | Array<DeleteResult> containing id, success, errors |
SOQL Query Example:
<salesforce:query config-ref="Salesforce_Config" doc:name="Query Active Accounts">
<salesforce:salesforce-query><![CDATA[
SELECT Id, Name, BillingCity, BillingCountry, AnnualRevenue,
(SELECT Id, LastName, Email FROM Contacts WHERE IsActive = true)
FROM Account
WHERE Type = 'Customer - Direct'
AND BillingCountry = ':country'
]]></salesforce:salesforce-query>
<salesforce:parameters><![CDATA[#[{'country': vars.targetCountry}]]]></salesforce:parameters>
</salesforce:query>
Upsert Operation with External ID:
<salesforce:upsert
config-ref="Salesforce_Config"
objectType="Account"
externalIdFieldName="ERP_Customer_Number__c"
doc:name="Upsert ERP Accounts">
<salesforce:records><![CDATA[#[
payload map (item) -> {
"ERP_Customer_Number__c": item.erpNumber,
"Name": item.companyName,
"Phone": item.phoneNumber,
"BillingCity": item.city
}
]]]></salesforce:records>
</salesforce:upsert>
[!IMPORTANT] UpsertResult Structure When
<salesforce:upsert>executes, each record inpayloadreturns anUpsertResultobject. Thecreatedproperty is a boolean:trueif a new record was inserted, andfalseif an existing record matchingexternalIdFieldNamewas updated.
2. Salesforce Streaming API & Replay Channel Listener
To capture real-time business events from Salesforce without polling, Mule uses the Replay Channel Listener (<salesforce:replay-channel-listener>), which connects to Salesforce's CometD/Bayeux event bus.
<flow name="salesforce-cdc-account-listener-flow">
<salesforce:replay-channel-listener
config-ref="Salesforce_Config"
channel="/data/AccountChangeEvent"
replayOption="ONLY_NEW"
doc:name="Account CDC Listener">
</salesforce:replay-channel-listener>
<logger level="INFO" message="#['Received CDC Event for Account ID: ' ++ payload.data.payload.ChangeEventHeader.recordIds[0]]" />
</flow>
Replay Options & Disaster Recovery:
Salesforce retains Streaming API events (Change Data Capture, Platform Events, PushTopics) in an event bus for 24 to 72 hours. The replayOption controls which events are processed upon connection:
| Replay Option | Replay Value | Behavior |
|---|---|---|
ONLY_NEW | -1 | Receives only new events broadcast after the listener connects. Any events generated while the Mule app was stopped are ignored. |
ALL | -2 | Replays all retained events currently in Salesforce's 24/72-hour event buffer upon startup. |
FROM_REPLAY_ID | Stored ID | Resumes event consumption immediately following a specific replayId token stored in an Object Store, guaranteeing zero message loss and preventing duplicates during server restarts. |
3. JMS Messaging: Queues vs. Topics & Acknowledgement Modes
The JMS Connector (mule-jms-connector) provides enterprise messaging capabilities supporting JMS 1.1 and 2.0 brokers (such as Apache ActiveMQ, Apache Artemis, IBM MQ, and Solace).
+-----------------------------------------------------------------------------------------+
| JMS MESSAGING PATTERNS |
| |
| 1. QUEUE (Point-to-Point): |
| [Producer] ---> [ QUEUE: order.processing ] ---> [Consumer 1] |
| \--> [Consumer 2] (Load Balanced) |
| * Exactly ONE consumer processes each message. |
| |
| 2. TOPIC (Publish-Subscribe): |
| [Producer] ---> [ TOPIC: order.events ] ---> [Subscriber 1 (Billing)] |
| |---> [Subscriber 2 (Inventory)] |
| \---> [Subscriber 3 (Audit Log)] |
| * EVERY active subscriber receives a copy of the broadcast message. |
+-----------------------------------------------------------------------------------------+
JMS Acknowledgement Modes:
Configuring how and when messages are acknowledged back to the JMS broker dictates reliability and redelivery behavior:
<jms:config name="JMS_Config" doc:name="JMS Config">
<jms:active-mq-connection brokerUrl="${jms.brokerUrl}" />
</jms:config>
<flow name="process-order-queue-flow">
<jms:listener
config-ref="JMS_Config"
destination="order.fulfillment.queue"
ackMode="AUTO"
numberOfConsumers="4"
doc:name="On New Message: Order Queue">
<jms:consumer-type>
<jms:queue-consumer />
</jms:consumer-type>
</jms:listener>
<!-- Flow Processors -->
</flow>
Detailed Acknowledgement Mode Comparison:
| Mode | XML Attribute | When Acknowledged | Failure / Exception Behavior |
|---|---|---|---|
AUTO (Default) | ackMode="AUTO" | Automatically acknowledged after the Mule flow completes successfully. | If an unhandled exception occurs (or flow terminates in On-Error Propagate), the message is not acknowledged and is returned to the broker for redelivery. |
IMMEDIATE | ackMode="IMMEDIATE" | Acknowledged immediately when the listener receives the message, before the flow executes. | If the flow fails or crashes, the message is lost forever from the broker and will NOT be redelivered. |
MANUAL | ackMode="MANUAL" | Developer explicitly invokes the <jms:ack> operation at a designated step in the flow using #[attributes.ackId]. | If <jms:ack> is not reached due to an error or branch, the message remains unacknowledged and is redelivered according to broker policy. |
DUPS_OK | ackMode="DUPS_OK" | Acknowledged lazily in batches by the broker session. | Reduces network overhead; duplicate messages may be delivered if the broker restarts before batch commit. |
[!WARNING] Avoid IMMEDIATE Mode for Critical Workflows Using
ackMode="IMMEDIATE"destroys message delivery guarantees. If the Mule runtime crashes or an unhandled database exception occurs halfway through processing, the message cannot be recovered from the JMS broker.
4. File & SFTP Connectors: Polling, Watermarking & Locking
Batch integrations frequently exchange data via flat files (CSV, XML, JSON, fixed-width) deposited on local file systems or remote SFTP servers. The File Connector and SFTP Connector share identical operation schemas.
<flow name="sftp-invoice-polling-flow">
<sftp:listener
config-ref="SFTP_Config"
directory="/inbound/invoices"
watermarkEnabled="true"
autoDelete="false"
moveToDirectory="/archive/invoices"
doc:name="On New or Updated File">
<scheduling-strategy>
<fixed-frequency frequency="1" timeUnit="MINUTES" />
</scheduling-strategy>
<sftp:matcher filenamePattern="*.csv" timeSinceLastModified="60000" />
</sftp:listener>
<logger level="INFO" message="#['Processing file: ' ++ attributes.fileName ++ ' Size: ' ++ attributes.size ++ ' bytes']" />
</flow>
Key File / SFTP Capabilities:
- Automated Watermarking (
watermarkEnabled="true"): Tracks file modification timestamps. Only files modified after the last recorded poll time are retrieved. - Partial-File Write Protection (
timeSinceLastModified): SettingtimeSinceLastModified="60000"ensures the listener ignores files that were modified within the last 60 seconds, preventing Mule from reading a large file while an external sender is still writing it. - Post-Processing Actions:
autoDelete="true": Deletes the source file immediately upon successful flow completion.moveToDirectory="/archive": Atomically moves the processed file to an archive directory.renameTo="#[attributes.fileName ++ '.bak']": Renames the file during the post-processing move.
5. Streaming, Repeatable Streams & Memory Management
When reading large files or high-volume database/JMS payloads, Mule 4 uses an internal Repeatable Streaming Engine:
+-----------------------------------------------------------------------------------------+
| REPEATABLE STREAMING ENGINE BUFFER |
| |
| Inbound Stream (File / JMS / DB) |
| | |
| v |
| +---------------------------------------------------------------------------------+ |
| | IN-MEMORY BUFFER (Default: 512 KB) | |
| | - Payloads < 512 KB processed 100% in RAM with zero disk I/O overhead. | |
| +---------------------------------------------------------------------------------+ |
| | |
| | (If Payload exceeds 512 KB) |
| v |
| +---------------------------------------------------------------------------------+ |
| | DISK-BUFFERED SPOOL DIRECTORY (Temporary .tmp swap files on disk) | |
| | - Overflow bytes spooled to disk, protecting JVM from OutOfMemory errors. | |
| | - Transparently cleaned up when the stream is closed. | |
| +---------------------------------------------------------------------------------+ |
+-----------------------------------------------------------------------------------------+
- Non-Repeatable Streams: Can only be read once. Reading the stream a second time (e.g., in a Logger and then a Transform Message) results in a
STREAM_ALREADY_CONSUMEDerror. - Repeatable In-Memory Streams: Keeps the entire stream in memory, allowing multiple components to read it without disk access.
- Repeatable File-Store Streams (Default): Keeps up to 512 KB in RAM, spooling excess bytes to temporary disk files. This allows unlimited sequential re-reads while guaranteeing the JVM heap never crashes due to multi-gigabyte files.
6. Exam Watch: Core Connector Scenarios
[!IMPORTANT] Salesforce Upsert External ID An Upsert operation requires specifying the exact API name of an External ID custom field (
externalIdFieldName="External_ID__c"). If omitted or misnamed, Salesforce rejects the operation.
[!WARNING] JMS Listener Default Ack Mode The default JMS acknowledgment mode is
AUTO, which acknowledges the message only after the flow successfully finishes. If the flow throws an error handled byOn-Error Propagate, the message is NOT acknowledged and is redelivered.
[!TIP] Replay Channel Listener -2 vs -1
-1(ONLY_NEW) listens only for future events;-2(ALL) replays all historical events currently residing in Salesforce's 24/72-hour streaming retention buffer.
A developer needs to synchronize customer records from an external ERP database into Salesforce. If an account with a matching ERP_Account_Number__c exists in Salesforce, it should be updated; otherwise, a new account record should be created. Which Salesforce Connector operation and configuration must be used?
A Mule 4 application listening to a Salesforce Change Data Capture channel (/data/OpportunityChangeEvent) suffers a power outage and remains offline for 6 hours. During the outage, 500 opportunities were modified in Salesforce. How should the developer configure the Replay Channel Listener (salesforce:replay-channel-listener) to process all 500 missed events upon application restart?
A Mule flow processes critical financial transactions consumed from a JMS Queue using <jms:listener ackMode="AUTO">. During message processing, a database insert component throws a DB:CONNECTIVITY exception, and execution enters an On-Error Propagate scope. What happens to the original JMS message at the message broker?
An integration flow reads multi-gigabyte CSV order files from an SFTP server using sftp:listener. A 5 GB file is currently being transferred. How does Mule 4's repeatable streaming engine handle this large payload during processing without triggering a java.lang.OutOfMemoryError?