After following the steps to configure your DataSync application for Salesforce, you can then configure the application to share data out of your Salesforce org. The DataSync application has the following tabs to give you access to its features. Contact support@perspectium.com with any questions.

Perspectium application tabs in Salesforce

Shares

The Shares tab contains the different options to share data out of your Salesforce org:


Dynamic Share

dynamic share allows for real-time sharing of Salesforce records as they are created, updated, and/or deleted. In other words, dynamic shares are caused by some triggering event (such as when cases are created, updated, or deleted). The data is shared to a subscriber, which can be the DataSync Agent, or any number of the other applications that Perspectium can integrate with.

When selecting the Dynamic Share option you are presented with the following options:

Create New Dynamic Share so you can create a new dynamic share to share out records real time for a selected table (SObject).

View Dynamic Shares to see the dynamic shares you previously created and so you can update and delete them.


When creating or editing a dynamic share, do the following to ensure the dynamic share is set up correctly:

  1. Click Save to first save the dynamic share configuration. After you save, the dynamic share show a preview of the Apex trigger that will be created to capture real time changes.
  2. Click Save Trigger to save the Apex trigger. Repeat these steps anytime you make changes to the dynamic share.

If you prefer, you can modify the trigger directly by doing the following:

Modify Salesforce Apex triggers

Salesforce Apex triggers for your Salesforce service integration indicate the conditions that will trigger your Salesforce dynamic share. Update the Apex triggers for your Salesforce dynamic shares to filter out data that is sent from Salesforce to another app. The conditions for the SOQL query that runs as part of a dynamic share's Apex trigger can be manually configured on the Apex Triggers page. To modify the default Apex triggers created for your Salesforce service integration, you will need to create a Base64 encoded condition and specify the fields you want to include in the dynamic share's outbound messages. 

First, make sure you have successfully installed DataSync. Also, for your Salesforce dynamic shares, make sure that the Active, Create, Update, and Include Attachment boxes are checked.

WARNING! If you plan to make additional changes to your Apex triggers after manually modifying them, follow the procedure via SOQL query (rather than modifying your Apex triggers in the dynamic share form) to ensure that the manual modifications to your triggers are not overridden.

Modify Apex triggers via SOQL queries


  1. Log into your Salesforce organization and click the icon in the upper left-hand corner of the screen. Then, click the Perspectium DataSync app.

  2. In the navigation bar near the top of the screen, click Dynamic Shares. Then, click into the dynamic share that you want to modify Apex triggers for.

  3. To modify the SOQL query in your parent SObject's Apex trigger, create a query using the dropdowns next to Filter Field (choose a field to filter on, an operator, and type a value in the textbox). Then, click Add Filter to see how the triggerWhere clause in your Apex trigger will be updated. To save your parent SObject Apex trigger, scroll down to the bottom of the form and click Save. The Parent Apex Trigger Preview window will then update its triggerWhere clause to include the filter you just created. Finally, click Save Trigger to save the changes you made to your dynamic share.

  4. To modify the SOQL query in the Apex triggers for child SObjects associated with the parent SObject you are dynamic sharing, scroll down to the Child Settings section. Choose any child records you want to include in your dynamic share by using the arrows to move available child records from the list on the left to the list on the right next to Include Child Records. Click to highlight the child record that you want to modify the Apex trigger for. Then, create a query using the dropdowns next to Child Filter Field (choose a field to filter on, an operator, and type a value in the textbox). Then, click Add Filter to see how the triggerWhere clause in your child Apex trigger will be updated. To save your child SObject Apex trigger, click Save Child Trigger. Finally, click Save and then Save Trigger to save the changes you made to your dynamic share.
Modify Apex triggers manually
  1. Log into your Salesforce organization and click the icon in the upper left-hand corner of the screen. Then, click the Perspectium DataSync app.

  2. In the Quick Find window on the left side of the screen, type and then click Apex Triggers (under Custom Code).

  3. Locate the SObject's Apex trigger that you want to modify. Apex triggers will be named in the following convention: PSP_<dynamic share name>_<child SObject name>_<parent SObject name>. Then, under the Action column, click Edit for the Apex trigger you want to modify.

  4. Replace the triggerWhere value with a Base64 encoded Apex trigger condition. For information on Apex trigger condition syntax, see Apex triggers. To Base64 encode your Apex trigger condition, you can use Base64encode.org.



  5. Optionally, you can also modify the fields to be included in the Salesforce dynamic share's outbound message. To do this, locate the persp.PSPUtil.createPspOutMessage function and modify the parameter for this function by including any table fields that you want to include in the outbound message when your Salesforce dynamic share triggers. Then, click Save near the top of the form to save your changes.



  6. Using Steps #3-5 as a guide, modify the Apex triggers for any Child SObjects included with your Salesforce dynamic share.

Since Apex triggers are considered code that requires test coverage, you will need to have a test class for your Apex trigger to deploy it into production. See the following for an example Apex trigger test class.

Salesforce Apex Trigger Test Class

Before deploying Apex triggers from sandbox to production, each trigger will require a test class to cover at least 75% of the trigger code.

A test class will need to be written to test object for the trigger code as follows:

  • Trigger Actions - If the dynamic share has insert, update and/or delete selected. The test class will need to do the respective action selected (i.e. insert the object).
  • Trigger Conditions - An object matching the dynamic share conditions will need to have matching action(s) (such as an insert).
  • Apex Object Requirements - Mandatory fields required to do the action(s) above. For example, if the dynamic share is on the Contract object which requires the AccountId field be populated in order to insert a new Contract object. The AccountId field is a reference field to the Account object and requires an Account be created first.
  • Extra Trigger Options - Any other additional related triggers (such as Attachment and ContentDocumentLink triggers created when selecting the Include Attachments option) created with the dynamic share to share out those related records that will also need to be tested for trigger code coverage.

See below test class for an example of testing a dynamic share Apex trigger created on the Contract object:

  • Trigger Actions - The insert and update actions are selected on the dynamic share so the test class inserts and updates Contract objects.
  • Trigger Conditions - The dynamic share is set to only trigger and executed when the Contract object's Status != 'Draft'. Contract objects are inserted with the Status = 'Draft' and then updated to 'In Progress'.
  • Apex Object Requirements - The Contract object requires the AccountId, Contract__Type__c, StartDate, EndDate, Preferred_Complement_Date__c fields to be populated. These fields are populated when created test Contract objects. Since AccountId is a reference field to the Account object, test Account objects are created first to use for this field.
  • Extra Trigger Options - The dynamic share has the Include Attachments option selected to trigger and share out attachments when they are added. Test Attachment and ContractDocumentLink objects are created to test these triggers and share out those objects. 
PSPContractTriggerTest
@isTest(SeeAllData=true)
global class PSPContractTriggerTest {
    private static testmethod void  TestPSPContractTrigger() {
        List<persp__psp_replicate_conf__c> shares = [select Id,persp__create__c,persp__update__c,persp__delete__c,persp__table__c from persp__psp_replicate_conf__c where persp__table__c='Contract'];
        System.debug('Found Share: ' + shares.size());
        for(persp__psp_replicate_conf__c share : shares){
            System.debug('processing table: ' + share.persp__table__c);
            SObject shareObj = Schema.getGlobalDescribe().get(share.persp__table__c).newSObject() ;

			//Account object is required to create a Contract
            Account testAccount = new Account(name='PSP_Test Account');
            insert testAccount;
            String testName = 'PSP_Test';
            List<Contract> contractList = new List<Contract>();
            for(Integer i = 0; i <= 200; i++){  
                Contract testContract = new Contract(  
                    AccountId = testAccount.id,
                    Name = testName + i,
                    Short_Description__c = testName,
                    StartDate = System.today() + 1,
                    EndDate = System.today() + 3,
                    Preferred_Completion_Date__c = System.today() + 2,
                    Status = 'Draft',
                    Contract_Type__c = 'Other'
                );
                    
                contractList.add(testContract);
            }
                
            insert contractList;
                
            if(share.persp__update__c){
                String q = 'select Id, Status from ' + share.persp__table__c + '  WHERE Short_Description__c =: testName LIMIT 1';
                List<Contract> sobjList = Database.query(q);
                if (sobjList.size() == 0)
                    continue;
                 
                System.debug('returned: ' + sobjList.size());
                System.assertEquals(sobjList.size(), 1);
                for(Contract o : sobjList){
                    o.Status = 'In Progress';
                    update o;
                    
              		
                    String body1='x';
                    Blob b = Blob.valueOf(body1);
                    Attachment attach1= new Attachment();
                    attach1.Name = 'Test Attachment';
                    attach1.ParentId = o.Id;
                    attach1.Body = b;
                    insert attach1; 
            
                    attach1.Name = 'Updates Test Attachment';
                    update attach1;
                    System.assertEquals(attach1.Name, 'Updates Test Attachment');
                    delete attach1;
                    
                    
                 
                    //ContentDocumentLink Test                    
                    ContentVersion contentVersion = new ContentVersion(
                      Title = 'Test',
                      PathOnClient = 'Test',
                      VersionData = Blob.valueOf('Test Content'),
                      IsMajorVersion = true
                    );
                    insert contentVersion;    
                    List<ContentDocument> documents = [SELECT Id, Title, LatestPublishedVersionId FROM ContentDocument];
                    
                    //create ContentDocumentLink  record 
                    ContentDocumentLink cdl = New ContentDocumentLink();
                    cdl.LinkedEntityId = o.id;
                    cdl.ContentDocumentId = documents[0].Id;
                    cdl.shareType = 'V';
                    insert cdl;
                    cdl.shareType = 'I';
                    update cdl;

					try {
 						Delete cdl;
					} catch (Exception e) {
    					System.debug('Error deleting ContentDocumentLink');
					}

                } // end for(Contract o : sobjList){
            } // end if(share.persp__update__c){
        } // end for(persp__psp_replicate_conf__c share : shares)
     } // end testmethod()
}  



Include child records

The Include Child Records option provides a way to share out child records of a parent record. This is done by creating Apex triggers so as to capture events on those child tables, and filtering to only share out child records related to the parent record.

After selecting the parent table on a dynamic share form, the Include Child Records option will populate with child tables that support Apex triggers. Select those tables where you want to share child records from.

For example, if you select the Case table for the dynamic share and want to share out comments on Case records, select the CaseComment table in the Include Child Records option:

Like attachments, this option currently only supports sharing out all fields of the child tables.

As is the case with the Apex trigger created for the parent table specified in the share, any triggers created for the child tables will be set to blank when the dynamic share is set as inactive and/or you remove a child table from the selected list (i.e. if you first select the CaseComment table in the Include Child Records option, and create a trigger for it, and then later you decide to remove the CaseComment table from the selected list). This is done to be consistent with the approach of not deleting Apex Triggers, since Apex triggers can only be created in sub-prod orgs and moved over to prod orgs. (i.e. once you delete an Apex trigger in production you can't recreate it without going through the process of doing it in a sub-prod).

Apex triggers on the child tables can be deleted but when the Apex trigger is deleted on the parent table, notably when the dynamic share itself is deleted.


Bulk Share

bulk share is a job that sends out bulk records from your Salesforce org as a pre-filtered range of data, at a point in time all at once. The data is shared to a subscriber, which can be the DataSync Agent, or any number of the other applications that Perspectium can integrate with.

When selecting the Bulk Share option you are presented with the following options:

Create New Bulk Share to create a new bulk share to share out records at a point in time for a selected table (SObject).

View Bulk Shares allows you to see the bulk shares you previously created and so you can re-execute them.


When creating a bulk share, you can Save the bulk share to save the bulk share or click Execute Now to save and execute the bulk share. Once a bulk has been executed, the bulk share's configurations cannot be changed but it can be executed again by clicking the Execute Now option again.

Some notable features for bulk shares:

Preview - The Preview button will allow you to get a preview of how records the bulk share will share out when executed.

Clone - To create a copy of this bulk share. This is useful if you have a current bulk share that's been executed and you want to use it with changes to some of the configurations without having to create a brand new bulk share and reconfigure from scratch.

Enable Confirmation - To have the DataSync Agent validate that it has received all the records shared out as part of this bulk share execution. The bulk share will send out compare messages that the Agent will use to validate records were received. If the Agent finds that a record is missing (by verifying the record exists when querying for it by the record's Id), it will send back a reshare message telling the Perspectium application in Salesforce to reshare those records. The application will create a new reshare bulk share (named Reshare <Bulk Share Name> Datetime i.e. Reshare AccountShare 2024-02-07 19:29:03) to share out the missing records and another compare message so the Agent can confirm its receive these records. This will repeat until the Agent has confirmed the records are all received.

Share Updates Since Then - To share records only since the last time this bulk share was executed. After the first run (in which all records will be shared based on any filter conditions you enter), the bulk share will then only share any records that were updated since the last time the bulk share executed (using the bulk share's Started time as the last time it executed). This is useful if you set up the bulk share in a scheduled bulk share to share out only changes on a scheduled basis.

Table Map - To specify a table map for transforming how records will be shared out.

(info) NOTEThe Table Map and Fields to Share options are not compatible with each other.


Scheduled Bulk Share

Schedule one or more bulk shares to run at a scheduled interval you choose. After creating a bulk share, you can add the created bulk configuration as a child record to be run under the schedule specified within your scheduled bulk configuration.

When selecting the Scheduled Bulk Share option you are presented with the following options:

Create New Scheduled Bulk Share to create a new scheduled bulk share and select which bulk shares to be run and at what intervals.

View Scheduled Bulk Shares allows you to see the scheduled bulk shares you previously created and modify their configurations


When creating a new scheduled bulk share (or modifying a current one), you can do the following:

  1. Select a date and time in the Scheduled Date Time field for when to start bulk sharing records, and the Days and Hours to repeat the process in the Repeat Interval field. 
  2. In the Available Bulk Shares, select which bulk shares you want to schedule.
  3. Check the Active box to activate the scheduled bulk share. 
  4. Click Save to save your changes.


Queues

The Queues tab contain the queues in the Perspectium Integration Mesh you use to share out data from your Salesforce org and to subscribe to data into org.

For sharing data out of your Salesforce org, you specify a Shared Queue where data will be saved into in the Perspectium Integration Mesh to be consumed by a target (such as the DataSync Agent consuming messages to save records into a target database).

For subscribing to data into your org (i.e. you want to consume messages from the Integration Mesh that was shared by a different source system), you specify a Subscribed Queue in the Integration Mesh you will be consuming messages from.

(info) NOTETo work with the Enable Confirmation bulk share feature, you will need to create a subscribed queue in the format of psp.out.salesforce.<instance>.<organization_name> in lower case and replacing spaces with _ so the Agent can send back messages for any missing records. The Instance and Organization Name can be found in Company Information

For example, in the above screenshot where the Organization Name is PSP DS and the Instance is NA244, you would create a subscribed queue named psp.out.salesforce.na244.psp_ds.


Some notable features when creating a new queue (or editing a current queue): 

Direction - The direction of the queue, if its for sharing data out of your org (Share) or to subscribe to data into your org (Subscribe).

Alias - A name as a reference to the queue. Alias are used to give a "name" to a queue so your dynamic share Apex trigger created in your sandbox org can be deployed in your production org. When migrating your Apex trigger from sandbox to production using change sets, the Apex trigger code cannot be changed. So using the same alias name when creating a queue in sandbox and creating a queue in production allows you to specify different queues in your sandbox and production orgs that can use the same Apex trigger.

Queue Encryption Key - (Optional) Enter an encryption key for any shares/subscribes that use this queue. If not entered, the default key entered in Properties will be used. To ensure compatibility with all encryption methods, you will have to enter an encryption key of at least 32 characters.

(info) NOTEBecause of how Salesforce encrypts sensitive information fields, the Queue Password and Queue Encryption Key will not be populated when you edit an existing queue. You do not have to re-enter these values when editing a queue unless you want to change their values. Leaving them blank when editing a queue and clicking Save will retain the current values.


Once you've created a queue and saved it for the first time, you can come back to the Queue's form and the following options will be available:

Get Queue Status - To check how many messages are currently in the queue in the Perspectium Integration Mesh. This will allow you to verify if your queue credentials are valid.

Show Encryption Key - To see the encryption key set for this queue. If an encryption was not entered, the message No encryption key set for this queue will be shown (in which case the default encryption key will be used).


Tools

Click here to learn more about the different tools available for the Perspectium application.


Messages

The Messages tab contain the messages being sent to and received from the Perspectium Integration Mesh.

Outbound Messages contains records that are queued to be sent to the Perspectium Integration Mesh. Once the messages have been sent their status will update to Sent

(info) NOTE: If the Status is at "Ready", the Time Processed field will be blank. Once the status is "Sent", you will be able to see how long it took for the outbound message to be sent.  

In the list view of Outbound Messages you will see the following options:

Delete All - To delete all messages in Outbound Messages. 

Delete replicator messages - To delete all messages in Outbound Messages with a topic of replicator.

Delete non-replicator messages - To delete all messages in Outbound Messages that do not have a topic of replicator.

(info) NOTE: The above delete options only delete messages in the Outbound Messages table in the Perspectium application in Salesforce to help quickly clean up data in this table. This does not affect the messages in the queues in the Integration Mesh.


Inbound Messages contains records that were shared to this Salesforce instance by other sources. The data flowing into this table will insert or update their respective tables and record once they are processed. 

When clicking on a message (both inbound and outbound), you will see a Decrypt Value option. This option will decrypt the message's value field (using the encryption key from the queue or the default key if a key wasn't set in the queue) so you can see the encrypted content that was sent/received from the Integration Mesh.


Dashboard

The Dashboard tab contain an overview of your data exchanges with the Perspectium application in your Salesforce org.


The Dashboard shows the following information:

Queues - A list of the queues you have currently configured. You can toggle between seeing all queues, shared queues and subscribed queues.

Messages - A list of outbound messages. You can toggle between seeing all messages, those that have a status of Error (to troubleshoot issues further), those that have a status of Ready (messages ready to be sent to the Integration Mesh) and Sent (messages that have already been sent to the Integration Mesh).

Bulk Share History chart - A bar chart showing how much data you've bulk shared by date. If you have not executed any bulk shares, the chart will show the message No bulk share execution history found. Run some bulk shares to show history here. (info) NOTESalesforce's charting capabilities will reflect an empty chart if you share a similar amount of data for all days (since it will appear as a line at the bottom of the chart). Once your bulk sharing levels start to differentiate, then the chart will show bars properly.

Bulk Shares - A list of the bulk shares you have currently configured.

Dynamic Shares - A list of the dynamic shares you have currently configured.

  • No labels