-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revamp listener support in Salesforce connector #6177
Revamp listener support in Salesforce connector #6177
Comments
Update
Streaming API (Existing one)Ref: https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/intro_stream.htm Allows you to receive updates or events from Salesforce in real-time without needing to constantly ask for them. Instead of your application repeatedly asking Salesforce if there are any updates, Salesforce sends the updates directly to your application as they happen.
Pub/Sub APIRef: https://developer.salesforce.com/docs/platform/pub-sub-api/guide/intro.html Lets you easily send and receive messages about events happening in a system. These events could be anything from real-time updates to changes in data.
Similarities:
Differences:
Considering the implementation and integration complexity, this migration would take some time as this is entirely new. Can't guarantee there wont be any breaking changes either. I tried out the event listener of the Pub/Sub API here. Works as expected and is pretty straightforward. |
Streaming API vs Pub/Sub APIStreaming APIThe Salesforce Streaming API utilizes the Bayeux Protocol and the CometD framework to enable real-time event streaming and communication between Salesforce servers and client applications. The Salesforce Streaming API primarily operates using HTTP/1.1, with support for HTTP/2 in some cases, depending on the client and server configurations.
Pub/Sub APIA newer API offering similar capabilities to the Streaming API but based on gRPC API and HTTP/2, providing efficient binary event messages., delivering binary event messages in the Apache Avro format, ensuring efficient publishing and delivery.
Considerations
In summary, if the application requires real-time updates and continuous streaming of events, the Streaming API might be a better choice. However, if you need more flexibility in event filtering and control over the types of events received, the Pub/Sub API could be a better fit. |
Design Review: Ballerina Salesforce ListenerOverviewThe Type Definitions# Salesforce listener configuration.
#
# + username - Salesforce login username
# + password - Salesforce login password appended with the security token (<password><security token>)
# + channelName - The channel name to which a client can subscribe to receive event notifications
# + replayFrom - The replay ID to change the point in time when events are read
# - `-1` - Get all new events sent after subscription. This option is the default
# - `-2` - Get all new events sent after subscription and all past events within the retention window
# - `Specific number` - Get all events that occurred after the event with the specified replay ID
# + environment - The type of salesforce environment
# - `PRODUCTION` - Production environment
# - `SANDBOX` - Sandbox environment
# - `DEVELOPER` - Developer environment
@display{label: "Listener Config"}
public type ListenerConfig record {|
@display{label: "Username", "description": "Salesforce login username"}
string username;
@display{label: "Password", "description": "Salesforce login password appended with the security token (<password><security token>)"}
string password;
@display{label: "Channel Name", "description": "The channel name to which a client can subscribe to receive event notifications"}
string channelName;
@display{label: "Replay ID", "description": "The replay ID to change the point in time when events are read"}
int replayFrom = REPLAY_FROM_TIP;
@display{label: "Environment", "description": "The type of Salesforce environment"}
string environment = PRODUCTION;
|};
# The type of Salesforce environment
# + PRODUCTION - Production environment
# + SANDBOX - Sandbox environment
# + DEVELOPER - Developer environment
public enum Organization {
PRODUCTION = "Production",
DEVELOPER = "Developer",
SANDBOX = "Sandbox"
}
# Replay ID `-1` to get all new events sent after subscription. This option is the default
public const REPLAY_FROM_TIP = -1;
# Replay ID `-2` to get all new events sent after subscription and all past events within the retention window
public const REPLAY_FROM_EARLIEST = -2;
# Contains data returned from a Change Data Event.
#
# + changedData - A JSON map which contains the changed data
# + metadata - Header fields that contain information about the event
public type EventData record {
map<json> changedData;
ChangeEventMetadata metadata?;
};
# Header fields that contain information about the event.
#
# + commitTimestamp - The date and time when the change occurred, represented as the number of milliseconds
# since January 1, 1970 00:00:00 GMT
# + transactionKey - Uniquely identifies the transaction that the change is part of
# + changeOrigin - Origin of the change. Use this field to find out what caused the change.
# + changeType - The operation that caused the change
# + entityName - The name of the standard or custom object for this record change
# + sequenceNumber - Identifies the sequence of the change within a transaction
# + commitUser - The ID of the user that ran the change operation
# + commitNumber - The system change number (SCN) of a committed transaction
# + recordId - The record ID for the changed record
public type ChangeEventMetadata record {
int commitTimestamp?;
string transactionKey?;
string changeOrigin?;
string changeType?;
string entityName?;
int sequenceNumber?;
string commitUser?;
int commitNumber?;
string recordId?;
}; Prerequisites to using the listener
Salesforce listener usageTo use the Salesforce listener in your Ballerina application, update the .bal file as follows: Step 1: Import listenerImport the import ballerinax/salesforce.events as sfdc; Step 2: Create a new listener instanceCreate a Notes:
sfdc:ListenerConfig configuration = {
username: "USER_NAME",
password: "PASSWORD" + "SECURITY_TOKEN",
channelName: "CHANNEL_NAME"
};
listener Listener sfdc:Listener = new (configuration); Step 3: Implement a listener remote functionThe Ballerina Salesforce Listener is designed to subscribe to Salesforce events, filter them based on specified criteria, and react to these events accordingly. Below is a generalized skeleton of the design. import ballerinax/salesforce.events as sfdc;
service sfdc:RecordService on sfdcListener {
# Triggers on a record update event.
remote function onUpdate(sfdc:EventData event) returns error? {
}
# Triggers on a new record create event.
remote function onCreate(sfdc:EventData event) returns error? {
}
# Triggers on a record delete event.
remote function onDelete(sfdc:EventData event) returns error? {
}
# Triggers on a record restore event.
remote function onRestore(sfdc:EventData event) returns error? {
}
} 4. Subscribing to EventsTo subscribe to events using the Ballerina Salesforce Listener:
5. Filtering EventsEvents can be filtered based on specific criteria within the service functions. For example: remote function onCreate(EventData payload) {
// Handle creation events
} SampleListenerConfig listenerConfig = {
username: username,
password: password,
channelName: "/data/ChangeEvents"
};
listener Listener eventListener = new (listenerConfig);
service RecordService on eventListener {
remote function onCreate(EventData payload) {
io:println("Created " + payload.toString());
}
remote isolated function onUpdate(EventData payload) {
json accountName = payload.changedData.get("Name");
if (accountName.toString() == "WSO2 Inc") {
io:println("Updated " + payload.toString());
} else {
io:println(payload.toString());
}
}
remote function onDelete(EventData payload) {
io:println("Deleted " + payload.toString());
}
remote function onRestore(EventData payload) {
io:println("Restored " + payload.toString());
}
}
Discussion Points
|
The changes proposed at the design review
# Configurations related to authentication.
#
# + username - Username to use for authentication
# + password - Password/secret/token to use for authentication
public type Credentials record {|
string username;
string password;
|};
# Salesforce listener configuration.
#
# + auth - Configurations related to username/password authentication
# + replayFrom - The replay ID to change the point in time when events are read
# + isSandbox - The type of salesforce environment, if sandbox environment or not
public type ListenerConfig record {|
Credentials auth;
int|ReplayOpitons replayFrom?;
boolean isSandbox = false;
|};
public enum ReplayOpitons {
REPLAY_FROM_TIP,
REPLAY_FROM_EARLIEST
}
service "data/ChangeEvents" on eventListener {
remote function onCreate(EventData payload) {
io:println("Created " + payload.toString());
}
}
{
"eventType": "created",
"objectType": "Account",
"recordId": "001XXXXXXXXXXXX",
"fields": {
"Name": {
"oldValue": null,
"newValue": "New Account Name"
},
"Industry": {
"oldValue": null,
"newValue": "Technology"
},
// Other fields that were modified
}
}
{
"eventType": "updated",
"objectType": "Contact",
"recordId": "003XXXXXXXXXXXX",
"fields": {
"FirstName": {
"oldValue": "John",
"newValue": "Jane"
},
"LastName": {
"oldValue": "Doe",
"newValue": "Smith"
},
// Other fields that were modified
}
}
{
"eventType": "deleted",
"objectType": "Opportunity",
"recordId": "006XXXXXXXXXXXX",
"fields": {
// No fields will be present in a delete event
}
}
{
"eventType": "undeleted",
"objectType": "Case",
"recordId": "500XXXXXXXXXXXX",
"fields": {
// No fields will be present in an undelete event
}
} Can add these types as the first parameter and the ChangeEventMetadata as the second optional parameter. |
+1 to the above changes. I have added a few more suggestions
listener Listener sfdc:Listener = new (*sfdc:ListenerConfig); Lets update listener initalisation as above, This ensures user only have to give auth details
|
This was de-prioritized due to support tasks and other feature requests. We have planned this for the upcoming sprint.
|
Description:
The salesforce connector currently supports the listener implementation through the
ballerinax/trigger.salesforce
package. Ideally this should be supported through theballerinax/salesforce
package itself.The text was updated successfully, but these errors were encountered: