Monday, December 31, 2018

VisualforceAccessMetrics - Way to find VF adoption and usage metrics

In Summer'17, Salesforce introduced "VisualforceAccessMetrics" object which can be used information about daily page view count of VF page.

You can query on this object using SOQL. Initially they provided below columns in this object:

  • ApexPageId - VF page Id
  • DailyPageViewCount - Page view count  on specific date
  • MetricsDate - captures the date on which daily page view count is calculated
In winter'19 release, Salesforce has introduced additional columns which is mentioned below:
  • ProfileId - Id of User profile who is accessing the VF page
  • LogDate - Specifies most recent page access date

Below are few sample queries which you run in developer console to find VF pages metrics
  • SELECT ApexPageId,DailyPageViewCount,Id,MetricsDate,profileId,logdate FROM VisualforceAccessMetrics order by MetricsDate DESC
  • SELECT ApexPageId,count(DailyPageViewCount) FROM VisualforceAccessMetrics group by ApexPageId
Query output:

SELECT ApexPageId,ApexPage.Name, DailyPageViewCount,MetricsDate,ProfileId, Profile.name,LogDate FROM VisualforceAccessMetrics order by MetricsDate DESC


Notes:
  • This object helps in identifying the page view count of VF in 24 hour time period.
  • This object helps in identifying the VF page which needs to be checked for lightning compatibility based on its usage.
  • This will also helps to identify which VF pages can be migrated to lightning.
  • You can identify which all VF pages are not at all used in organization and can be helpful in metadata clean up.
  • This object contain information about VF page usage for last 90 days only.
Hope this will help!!

Monday, December 24, 2018

How to set or get picklist (drop down) values in Lightning Components

Through this blog, I am going explain different syntax which can be used to create drop down (picklist) in lightning along with setting their their default values and fetching the user selected values in controller.js functions.

So will start with basics, if we already know different picklist or dropdown values then we can directly specify then in lightning markup as shown in below syntax:

Static Picklist

<lightning:select name="cStat" label="Case Status" value="New" aura:id="statusPicklist" >
<option value="">choose one...</option>
<option value="New">New</option>
<option value="In Progress">In-Progress</option>
<option value="Resolved">Resolved</option>
<option value="Closed">Closed</option>
</lightning:select>


"value" attribute  in lightning:select helps in pre-populating the default picklist value.

If you need to fetch the selected picklist value in controller.js, then use below syntax:

var selectedPicklistValue= component.find(“statusPicklist”).get(“v.value”);

Attribute Association with lightning:select

You can associate any attribute with lightning select and use that in "value" attribute of lightning select as shown below:

<aura:attribute name="ltngSelectedvalue" type="string" default="New"/>
<lightning:select name="cStat" label="Case Status" 
value="{!v.ltngSelectedvalue}" aura:id="statusPicklist" >
<option value="">choose one...</option>
<option value="New">New</option>
<option value="In Progress">In-Progress</option>
<option value="Resolved">Resolved</option>
<option value="Closed">Closed</option>
</lightning:select>

So in controller, you can directly get the value of attribute associated with lightning:select in order to get selected value for picklist.

var selectedPicklistValue= = component.get(“v. ltngSelectedvalue”);

Dynamic Picklist

When you are not sure of picklist options, then you can use dynamic picklist option. Different scenarios includes like passing picklist options from apex controller or using describe to get values for custom fields (picklist) created in salesforce.

Scenario 1

If the picklist label (displayed on UI) and values are similar then you can create an attribute of type "List" and use "aura:iteration" to create picklist options dynamically on UI. Below is sample syntax:

<aura:attribute name="options" type="List" 
default="['New','In Progress','Resolved','Closed']"/>
<aura:attribute name="ltngSelectedvalue" type="string" default="New"/>
<lightning:select name="cStat" label="Case Status" 
value="{!v.ltngSelectedvalue}" aura:id="statusPicklist" >
    <aura:iteration items=”{!v.options}” var=”opt”>
<option value="{!opt}">{!opt}</option>
    </aura:iteration>
</lightning:select>

Scenario 2

If picklist label on UI and values corresponding to then are different, then you can create a wrapper in apex class which contains 2 variables and return list of wrapper as different picklist options to lightning component attribute.

Public class picklistWrapper{
Public string pickListLabel;
Public string pickListValue;
}

Below is sample apex class which can be used to get picklist values using wrapper variable

Now in lightning component, you can call this apex method to fetch case status values and set it in attribute of type "object".
<aura:attribute name="options" type="Object"/>
In controller, store response from apex in variable and set the aura attribute

var apexResponse=response.getReturnValue();
//set response to attribute value
component.set("v.options",apexResponse);

In order to learn how to call apex method from lightning component refer below URL:
Calling Apex Method from Lightning Component

Below is sample code:

<!-- set options attribute through controller.js function call-->
<aura:attribute name=”options” type=”Object”/>
<aura:attribute name="ltngSelectedvalue" type="string"/>
<lightning:select name="cStat" label="Case Status" 
value="{!v.ltngSelectedvalue}" aura:id="statusPicklist" >
    <aura:iteration items=”{!v.options}” var=”opt”>
<option value="{!opt.pickListValue}">{!opt.pickListLabel}</option>
    </aura:iteration>
</lightning:select>

How to get selected picklist value on change event

You can also use onchange event on lightning:select to store the selected value by user in some aura:attribute.

<aura:attribute name=”options” type=”Object”/>
<lightning:select name="cStat" label="Case Status" aura:id="statusPicklist" 
onchange="{!c.onChange}">
<aura:iteration items="{!v.options}" var="opt">
<option value="{!opt.pickListValue}">{!opt.pickListLabel}</option>
</aura:iteration>
</lightning:select>

In controller.js, use below function:

onChange: function (cmp, event, helper) {
var selPickListValue = event.getSource().get("v.value");
        console.log('******selPickListValue :'+selPickListValue );
}

Note:

  • Event handler helps in identifying which markup element have been changed.
  • You can use event to get user selected element. Suppose user change the dropdown, value then by using event methods you can identify which dropdown value was changed by user along with its value.
  • You can get any attribute value of component through which user interacted on UI. for example event.getSource().get("v.name") will return "cStat" which is name attribute in lightning select.

Hope this will help!!!

Saturday, December 15, 2018

SALESFORCE INTEGRATION ARCHITECTURE DESIGNER : Things to consider before appearing for this exam

I have completed "Salesforce Certified Integration Architecture Designer" exam last week and with this I have started my journey for "System Architect".

I have successfully completed "Application Architect" credentials and if you would like to prepare for that then refer below blogs:

Data Architecture and Management Designer : Exam preparation guide and tips
Sharing and Visibility Designer : Exam preparation guide and tips

I have started preparing for this exam 2 months back and started with Resource guide. It contains all the required links for salesforce documentation and videos related to this exam.

After completing the resource guide, i started with Architect Journey: Integration Architecture trailmix. Lots of content in trailmix are already covered in resource guide. Best thing about trailmix is thing you can mark what all topics you have covered.


Now I will specify different points you need to know before appearing for exams.

STREAMING API
  • It is based on Publish/Scribe modal.
  • Whenever you have to notify user in Salesforce UI or external system about any changes to records, then use this API. 
  • By Using Streaming API, there is no need for external system to continuously pooling into salesforce to find any data updates.
  • In Streaming API, you create a channel by creating "Push Topic" and external system subscribe to this channel.
  • In "Push topic", you specify the query which identifies whether event will be generated for data change. Once event is generated , then it is evaluated based on conditions defined on "Push Topic" to identify whether notification needs to be send to channel or not.
  • SOQL queries with relationship are not supported in "Push Topic".
  • SOQL queries without Id in select statement are also not supported in "Push Topic". So you always need to add Id in select query.
  • Connection between salesforce and external system is maintained through long pooling concept.
  • Streaming API does not guarantee reliable delivery of notifications. Streaming servers do not maintain client state and do not keep track what is being delivered. 
  • Streaming API maintains sharing and visibility of data for user. External system will only receive information based on User access in Salesforce.
  • Streaming API sends information in JSON format.
  • If salesforce server is stopped due to some reasons, then client has to create connection again. Also if messages are processed but not yet delivered, will be lost if salesforce server restarts or stopped working.
  • Avoid sending multiple message in single request as there is limit of 23,768 bytes for HTTP request POST body.

BULK API
  • Bulk API is used to either export or import large volume of data. 
  • Bulk API is asynchronous process and data upload happen in parallel on servers.
  • Parallel mode is default for Bulk API. 
  • You may face "Record lock Errors" if using Bulk API in parallel mode. Try to group records based on parentIds to avoid record locking errors.
  • If you still face "Record Lock Error" then use BULK API in serial mode.
  • Currently base64 fields are not supported in queries with the Bulk API.
  • You can monitor BULK API jobs via API or Admin setup (Web UI).
  • A batch can have a Completed state even if some or all of the records have failed. If a subset of records failed, the successful records aren't rolled back. Likewise, even if the batch has a Failed state or if a job is aborted, some records could have been completed successfully.
  • When you get the batch results, it's important to look at the Success field for each result row to ensure that all rows were processed successfully. If a record was not processed successfully, the Error column includes more information about the failure.

OUTBOUND MESSAGES

Refer below link for complete information about outbound message

Outbound Messages : Implementation Tips and Considerations

INTEGRATION PATTERNS

There are lot of question on identifying correct integration patterns. Different scenarios will be given and being integration architect, you need to specify correct pattern.

For example, if there is need to send information to external system which is reliable even if external system is down while sending information, then implement inbound integration.

For complete details on different integration patterns and their use case, please refer below URL:
Integration Patterns and Best Practices for Salesforce - Part 1
Integration Patterns and Best Practices for Salesforce - Part 2

DATA BACKUP PROCESS
  • Use Bulk API, if you need to take salesforce data backup (large volume) in your data warehouse.
  • SOAP API provides 2 methods (getUpdated() and getDeleted()) which can be used to backup data which is changed.
  • The Replication API is the most reliable method for data replication. It includes two functions, getUpdated and getDeleted, the former describes newly created and updated records, while the latter indicates records that have been deleted.
  • The API returns the ID of every changed object that is visible to you, regardless of what change occurred in the object, based on SystemModstamp field information if available.
  • The replication API has a specific advantage that it is designed to make sure you can't miss records and won't retrieve duplicates, both of which are possible when directly querying based on CreatedDate or LastModifiedDate fields (because of in-flight transactions that won't appear in queries until they are fully committed).
NAMED CREDENTIALS Vs REMOTE SITE SETTINGS
  • Whenever callout is performed from salesforce, then you need to specify the endpoint in remote site settings.
  • System will give "Unauthorized endpoint URL" error if endpoint is not specified in remote site settings.
  • A named credential specifies the URL of a callout endpoint and its required authentication parameters in one definition. To simplify the setup of authenticated callouts, specify a named credential as the callout endpoint.   
  • If you specify the endpoint URLs in named credentials then no need to specify it in remote site settings.
  • Named credentials simplify utilizing oAuth for apex callout and store credentials in maintainable way.
  • If you have multiple orgs, you can create a named credential with the same name but with a different endpoint URL in each org.
  • Named credentials support basic password authentication and OAuth 2.0.
  • To reference a named credential from a callout definition, use the named credential URL. A named credential URL contains the scheme callout:, the name of the named credential, and an optional path. For example: callout:My_Named_Credential/some_path.
  • Named Credential access is provided through profile or permission sets.
MIDDLEWARE (ETL TOOLS)
  • Always prefer utilizing middleware if you want to integrate salesforce with multiple system.
  • If there is need to extract and transform data from salesforce and then to send it to external system, then middleware is best option.
  • Middleware helps in Orchestration, Error handling and logging. 
REST API
  • REST API is synchronous in nature and follows Remote Process Invocation—Request and Reply pattern.
  • This is general integration API. It supports XML and JSON. It is light weight. It is state less API.It works with access_token(using OAuth2.0) or session Id in HTTP header.
  • HEAD method is used to retrieve resource metadata. GET method is used to fetch data, POST to create records, DELETE to delete record and PATCH to update record.
  • PATCH method is not supported in HTTP request in apex so in endpoint URL specify parameter "_HttpMethod=PATCH"
  • REST API can be used for small set of data.
  • REST API support XML and JSON format.
  • Workbench is bet tool to test Salesforce REST API resources.
CANVAS APPLICATION
  • Canvas app is used to integrate external web applications inside salesforce UI.
  • Canvas app can be used within VF page, chatter tab, publisher action, salesforce console, as a feed item and salesforce 1 navigation item.
  • Force.com canvas provide ajax based javascript SDK that allow embed application to easily access salesforce data layer and provide UI integration capabilities.
  • Canvas app is defined within connected app framework.
  • Canvas allows use of  HTTP POST and HTTP GET.
  • It use signed request as default authentication method (use HTTP POST).
CONNECTED APPS
  • A connected app integrates an application with Salesforce using APIs. Connected apps use standard SAML and OAuth protocols to authenticate, provide single sign-on, and provide tokens for use with Salesforce APIs. In addition to standard OAuth capabilities, connected apps allow Salesforce admins to set various security policies and have explicit control over who can use the corresponding apps.
  • Connected Apps are not available in all org but can be installed in all orgs.
  • “Customize Application AND either Modify All Data OR Manage Connected Apps” permission is needed to read, create, update, or delete connected apps.
  • Write a custom connected app handler in Apex to customize the behavior of the connected app. Create a class that extends the ConnectedAppPlugin Apex class, and associate it with the connected app. The class can support new authentication protocols or respond to user attributes in a way that benefits a business process.
  • If you enter multiple callback URLs, at run time Salesforce matches the callback URL value specified by the app with one of the values in Callback URL. It must match one of the values to pass validation. Separate multiple callback URLs with line breaks.
  • The callback URL field has a limit of 2000 characters, cumulatively. If you enter several URLs and they exceed this limit, create another connected app to manage more callback URLs.
  • Connected app can be configured to receive push notifications.A push-enabled connected app can support only one mobile platform. To support push notifications on Android and iOS versions of your mobile app, create a connected app for each platform.
SALESFORCE TO SALESFORCE INTEGRATION
  • Salesforce to Salesforce can be used to create this data sharing relationship. Salesforce to Salesforce is a natively supported feature of the Force.com platform, and easily enables two trading partners to share relevant data records between orgs.
  • Enable the “Manage Connections” permission on the profile of the users in order to configure salesforce to salesforce.
  • Salesforce to salesforce can not be used to connect sandbox with production.
CONCURRENT APEX ERRORS

If you are getting error saying "Unable to process request. Concurrent requests limit exceeded." then it means concurrent Apex requests exceed governor limitations for your Salesforce organization.

Cause:
  • Poorly coded Apex
  • Synchronous callouts from Visualforce pages
  • Inefficient SOQL queries
Resolution
  • Perform synchronous callout from VF pages (use continuation framework to avoid excessive concurrent Apex errors and decreased performance).
  • Use efficient SOQL queries. Use the Query Plan Tool to validate and optimize SOQL performance.

LOGIN RATE EXCEEDED

Refer below URL to know more about this error
Sign in Error: 'Login Rate Exceeded'

CHATTER REST API
  • Enables integration with Salesforce Chatter
  • Give access to chatter feed and social data(users, groups, followers and files).
  • Use this API if you want to integrate mobile apps with Chatter.
  • Chatter REST API provide built in pagination(provides nextpageurl, previouspageurl and currentpageurl in response) and pre-aggregation of data from different objects.
  • Chatter REST API provide structured data which can be used for rendering on website.
  • Returned information is localized to the user's time zone and language.
  • Rate limiting for Chatter REST API is per user, per application, per hour. The rate limiting for SOAP API and REST API is by organization.
SOAP API
  • Just go through differences between Enterprise and partner WSDL.
  • SOAP API also provide getUpdated() and getDeleted() methods which can be used for incremental data backup.
  • SOAP API integrate at Application layer.
  • SOAP queries return 500 records per batch and can return max of 2000 records.
  • This API has concurrent API request limit.
  • SOAP API provides CRM specific methods (like convertLead()), Utility methods (like getUserInfo(), setPassword() etc) and describe methods (like describeGlobal(), describeSobject() etc).
Security Considerations
  • Use TLS protocol to create a secure channel between Salesforce and other system.
  • Always base64 encode the data before performing the callout in apex to securely transport sensitive data from Salesforce over an unsecure network connection.
  • Custom webservices do not enforce record sharing and visibility. Make sure you are not sending any sensitive data in custom webservices.
Custom Webservices/REST services
  • If you want to built API through which external application can update multiple objects in salesforce, then create custom webservices or apex REST services.
  • Make sure you are not passing sensitive data to external system while create custom webservices or Apex REST services as these run in system mode.
  • If you need to send information combining from multiple object to external system then use custom webservices or apex REST services.

Hope this will help!!

Wednesday, December 12, 2018

Outbound Messages : Implementation Tips and Considerations

Outbound Messages are one way and asynchronous method to send some information from Salesforce to External systems. Best thing about Outbound messages is that it is declarative and no coding is required for this.

Outbound message follows "Remote Process Invocation—Fire and Forget" Integration pattern.

If you are planning to appear for "SALESFORCE CERTIFIED INTEGRATION ARCHITECTURE DESIGNER" exam then this blog will be helpful.

Below are implementation tips which need to know:

Reliable

  • Outbound Message has in-built retry mechanism. 
  • Messages will be queued locally. A separate background process performs the actual sending, to preserve message reliability
  • If the endpoint is unavailable, messages will stay in the queue until sent successfully, or until they are 24 hours old. After 24 hours, messages are dropped from the queue.
  • If a message cannot be delivered, the interval between retries increases exponentially, up to a maximum of two hours between retries.
  • Messages are retried independent of their order in the queue. This may result in messages being delivered out of order.
  • Source object may change after a notification is queued but before it is sent, so the endpoint will only receive the latest data, not any intermediate changes. Because a message may be delivered more than once, your listener client should check the notification IDs delivered in the notification before processing.

Security Considerations
  • All Outbound messages are sent from Salesforce IP address. Make sure that Salesforce IP addresses are white listed in external system.
  • Using SSL/TLS provides confidentiality while data is transported across the internet.
  • You can pass user session Id in outbound messages so that external system can callback and update data back in salesforce.
  • The organization Id is included in each message. Your client application should validate that messages contain your organization Id.
How to prevent circular changes with outbound messaging?


It’s possible to create circular changes with outbound messaging. For example, user updates contact which trigger outbound message to external application. After this external application will update contact back in salesforce which can again trigger outbound message. To prevent these circular changes, you can disable a user’s ability to send outbound messages.

To disable outbound message notifications for a user, deselect Send Outbound Messages in the user’s Profile. 

We recommend specifying a single user to respond to outbound messages and disabling this user's ability to send outbound messages.
  • Select Salesforce user while creating OM, to use when sending the message by specifying a username in the User to send as field. The chosen user controls data visibility for the message that is sent to the endpoint.
  • Select Include Session ID if you want a sessionId to be included in the outbound message. Include the sessionId in your message if you intend to make API calls back to Salesforce from your listener. The sessionId represents the user defined in the previous step and not the user who triggered the workflow.
  • The API Version for OM can only be modified by using the Metadata API not from UI.
Tracking Outbound Message Status

To track the status of an outbound message, from Setup, enter Outbound Messages in the Quick Find box, select Outbound Messages, and then click View Message Delivery Status. You can perform several tasks on this page.
  • View the status of your outbound messages, including the total number of attempted deliveries.
  • View the action that triggered the outbound message by clicking any workflow or approval process action ID.
  • Click Retry to change the Next Attempt date to now. This action causes the message delivery to be immediately retried.
  • Click Del to permanently remove the outbound message from the queue.
Capabilities of Outbound Messages
  • Message can be delivered in out of order fashion as it is asynchronous process.
  • Outbound Messages uses SOAP based calls. It can not be used for system which doesn't support SOAP API's.
  • Organization Id is passed in all messages. 
  • Session Id can be passed to implement 2 way communication by performing callback to Salesforce from external system
If you want to learn about Integration patterns then refer below blogs:

Hope this will help!!