Force.com IDE and Version Control

The following is a portion of the notes that I took while viewing the Managing Development with Force.com Training class, which is part of the Spring 2013 Premier Online Training available from Salesforce. This training class is one of the recommended training courses needed to complete the Salesforce Force.com Advanced Developer certification.

Development with the Force.com Platform

  • Your development environment should consist of the following two tools:
    • At least one dedicated Sandbox – Allows you to use the Setup menu to customize applications, modify metadata and synchronize changes
    • Force.com IDE – Used to develop code, customize and create metadata in Bulk, deploy metadata, support version control and synchronize file changes

Eclipse

  • Eclipse is an extendable integrated development environment that supports a variety of plug-ins, such as the Force.com IDE.
  • It can be downloaded at http://www.eclipse.org/downloads.
  • Force.com IDE can be used to:
    • Develop Apex triggers, classes, VisualForce pages and controllers
    • Debug code
    • Run unit tests and generate code coverage results
    • Deploy Force.com applications
  • The Force.com plug-in can be installed by doing the following:
    • Opening Eclipse and going to Help and Install New Software.
    •  You then click the Add Button and enter http//www.adnsandbox.com/tools/ide.install as the location and Force.com as the Name. This will add Force.com to the list of available software
    • Select Force.com from the Available Software list and Next to continue
    • Click Next again from the Install Details dialog box
    • Select “I accept the terms..” radio button and click Finish to complete the install
    • You will have to restart Eclipse when finished.

Navigating in the Force.com IDE

  • Once Eclipse opens again, click Window and Open Perspective and then select Force.com.
  • In the Package Explorer pane (left), you can open and explore code in your project
  • The Code Editor pane(middle) displays all open code in separate tabs. Files that are not saved, have an asterisk after the file name in the tab.
  • The Outline pane(right) shows the schema of the current file open in the code editor
  • The bottom pane consists of several tools :
    • Problems Tab – Display errors when code is compiled
    • Apex Test Runner Tab – Monitors test methods and allows you to run unit tests
    • Execute Anonymous Tab – Execute anonymous blocks of Apex code
    • Synchronize Tab – Synchronize project with the server
    • Force.com IDE Log Viewer – monitor events and diagnose problems in the IDE
  • Project Organization
    • The src folder in your project will contains sub folders for all metadata and code
    • Salesforce.schema provides access to the schema browser
  • Menus
    • New menu – Get to by clicking File or right-clicking anywhere in package explorer
      • To create a new project:
        • click File | New | Force.com Project
        • Specify the project name, username, password and environment and click Next
        • Select metadata components to include and select all click Finish
    • Force.com menu – Context menu that appears by right-clicking a folder or file and selecting Force.com. From here you can select any of the following:
      • Work Offline/online – When saving a file in online or offline mode, it will first save the file to your local machine and then it will attempt to save to the server. The save operation performs a syntax check and if errors are found, they are displayed in the Problems tab and the save will fail. You can double click on an error in the Problems tab and then go right to that location in the code. You can also hover over the error and warning icons to check for the error description.
      • Execute Anonymous
      • Show in Salesforce Web – Opens your browser and directly logs you in to your org with your credentials
      • Refresh from Server – copies the changes from the server and overwrites local files
      • Save to Server – After creating a project, you can work in either online (default) or offline mode. When offline, you must explicitly save changes to the server by using Save to Server or Synchronize with Server options.
      • Synchronize with Server copies files, but if conflicts are detected, it gives you one of three options to resolve:
        • Use your local project files
        • Use the Server files
        • Compare the differences through the diff tool and merge them
      • Deploy to Server
      • Add/Remove metadata components
      • Project Properties

Schema Browser

  • Allows you to execute SOQL queries and view query results, but you cannot modify the schema
  • It builds a SOQL statement by selecting fields or objects from the Schema pane. You can also just type in the query yourself.
  • Useful for looking at relationships between objects, as well as data types for specific fields

Coding Tools

  • IDE provides support for:
    • Visualforce pages – The Insert Merge Field option provides assistance with field name references and shows a browseable outline of nested XML structure
    • Apex – The code outline lets you go directly to areas of the code and it provides syntax highlighting.
      • It will show which lines have an error and gives you tabbed views of source code and the XML metadata definition.
      • You can also use the Execute Anonymous tab to execute code on the fly
      • The Apex test runner allows you to troubleshoot code, monitor performance and check for resource usage.
      • You can also re-run unit tests directly from this tab. The results will show you test failures as well as which code has code coverage and what percentage is covered
    • XML-based metadata development – You can directly modify the XML-based metadata, which may be easier to use than the Setup menu when you have to add several fields.
    • Documentation – The latest Force.com documentation is available through the online help

Version Control

  • Version control is a repository that is the central store of files with a system that helps to manage and track changes made to these files.
  • Useful for tracking code changes and allows you to rollback changes if necessary
  • Allows for conflict resolution if files on your local system do not match what is stored on the server.
  • Supports Branching, which lets you branch your code and is necessary when doing parallel development. You can make changes to branches independently and then merge branches back into the main branch when complete. Ideally, you would have the following branches:
    • Developer Branch – Used for each developers line of development. Allows them to save incomplete work without interfering with others.
    • Project Branch – considered the main development line. Should contain working builds
    • Release Branch – Merged here when all changes have been compiled and tested in Project branch.
    • Note that not all customizations through the Setup are available through the metadata API and therefore these will need to be reproduced for each org.
    • When you checkout a project for the first time, you need to apply the Force.com nature at the project level. This is done by selecting Add Force.com Nature at the project level.
    • You can click Project properties from the Force.com context menu to connect the project to your Salesforce organization.
    • Because development is being done by multiple developers, most companies do nightly builds to verify the validity of check-ins (see image below)

BuildProcess

Force.com Migration Tool and Version Control

  • Maintains version of your application files as a script-based alternative.
  • Provides a bridge between the code running in the cloud and your version control system.
  • Requires manual configuration in the target organization

Understanding Force.com Sandbox Environments

The following is a portion of the notes that I took while viewing the Managing Development with Force.com Training class, which is part of the Spring 2013 Premier Online Training available from Salesforce. This training class is one of the recommended training courses needed to complete the Salesforce Force.com Advanced Developer certification.

Sandboxes

  • Sandboxes are a clone of an entire production environment that allows developers to develop and test without risking production data.
  • There are three types:
    • Full – copies the entire prod org (although you can choose to omit some data and have it load faster)
    • Configuration-only – copies only the configurations and does not copy any data. But, you can load up to 500MB of data
    • Developer – Similar to the Configuration-only, except you can only load up to 10MB of data

SandboxComparisonChart

Sandboxes and Editions

  • Enterprise Edition includes 1 developer sandbox for Apex development
  • Unlimited Edition includes 1 full, 5 config-only, and 15 developer sandboxes
  • You can buy additional sandboxes of any type and buying one of the larger sandbox types includes some free developer sandboxes for support

SandboxLifecycle

Development Lifecycle: Training

  • Sandboxes are great for Training
  • You should use a config-only or a full sandbox for training and load it using the data loader and a standardized training dataset

Managing a Sandbox

  • Can be managed through Setup -> Data Management -> Sandbox. From here you can refresh existing sandboxes and add new ones if your license allows for it. This page will show how many sandboxes you are using and how many more you can create.
  • When refreshing a sandbox, you can rename it. You activate a refreshed sandbox to start fresh. Full Sandboxes can only be refreshed every 29 days, but all other types can be refreshed in only a day.
  • The refresh process involves the following steps:
    1. Administrators request a refresh
    2. Request enters a processing queue
    3. Request remains in copying stage until complete. Changes made to a production org during this time may or may not be reflected in the copy
    4. Email notification is sent when copy is complete
  • When the refresh is complete, an activation link becomes available. Administrators must activate a new sandbox copy to enable login access. This will also deactivate the existing copy and the previous copy will be deleted shortly after.
  • You can delete sandboxes at anytime, but you cannot replace a deleted sandbox with a new one only after the refresh interval for the deleted sandbox has passed. Keep in mind that sandboxes may be deleted if licenses are downgraded. If you need fresh sandboxes, it is best to refresh the sandbox instead of deleting it.
  • Sandboxes that are not activated, locked or inactive within 30 days, will be removed. Administrators will get at least 2 notifications before un-activated or locked sandboxes are removed and they will get at least 3 notifications before inactive sandboxes are removed.
  • Sandboxes are hosted on different servers than production and to access them you can click the Login link from the Manage Sandboxes area, or you can browse to the following url: http://test.salesforce.com and use your production username, along with a dot and the sandbox name. For example, if your production login is jdoe@somecompany.com and your sandbox is named “dev”, then the login would be jdoes@somecompany.com.dev.

Sandbox Considerations

  • Services that are disabled in the sandbox include:
    • Case escalation
    • Opportunity reminders
    • Contract expiration warnings
    • The ability to test Google AdWords
    • The ability to create Salesforce sandboxes
  • Newly created sandboxes have the “System email only” option set, which helps to prevent emails from being accidentally sent to production users.
  • When developing applications, you can create custom links to access records in Salesforce. It is much better to use relative URL’s, rather than absolute ones. For example:

Absolute URL:https://na1.salesforce.com/00ghy000000RGnY&okI={!AccountId}
Relative URL: /00ghy000000RGnY&okI={!AccountId}

  • External systems may access your org using URL’s. When working with a sandbox, you will have to make sure these URL’s point to the sandbox and not production. You will also need to modify URL’s for outbound messaging and web service callouts.
  • Sandboxes are typically upgraded weeks before a new release and you need to be careful when scheduling a release of your own development code. If you try to release code to production from a sandbox that was upgraded before production, your code may not work properly.

Managing Data

You can use one of the following tools:

  • Data Export – You can export data by going to Setup -> Data Management -> Data Export. This will create a copy of all your data in salesforce.com. It will create csv files and you can choose when and what to download. You can also schedule a data export (weekly or monthly) or export immediately using the Export Now button. Keep in mind that the Export Now button is only available if a week has passed since your last export.
  • Data Loader – The data loader is a client application used to bulk import or export data from csv files. You can download it by going to Setup -> Data Management -> Data Loader. It provides an alternate command line interface and support for all objects (standard and custom).
  • Programmatically - You can manage data programmatically with the Force.com Web services API, which is good for handling a small amount of data or the REST-based Bulk API, which is good for handling large datasets.

Apex Class Notes – Advanced Topics

The following is a portion of the notes that I took while viewing the Apex Training class, which is part of the Spring 2013 Premier Online Training available from Salesforce. This training class is one of the recommended training courses needed to complete the Salesforce Force.com Advanced Developer certification. Go here to get a PDF copy of the entire class notes.

Dynamic Apex Components

  • Enables you to create more flexible applications by providing you the ability to access sObject and field metadata descriptions
  • Allows you to write dynamic SOQL and SOSL queries and dynamic DML
  • Consists of several components:
      • Schema Describe – way to programmatically discover info about the current org schema. You can use the following to get a map of the schema:

    Map<String,Schema.sObjectType> gd = Schema.getGlobalDescribe();

      • Dynamic SOQL – allows you to build a SOQL string at runtime.  These are vulnerable to SOQL injection. To avoid this, you need to use the escapeSingleQuotes method. This method adds the escape character (\) to all single quotation marks in a string that is passed by a user.
      • Dynamic SOSL – creates a SOSL string at runtime. Like with dynamic SOQL, you use escapeSingleQuotes(string) to prevent SOSL injection.
      • Dynamic DML – provides the ability to perform DML operations on sObjects in which the type of the object is not known.

Apex Describe structures

  • Token -  lightweight reference to an sObject or a field
    • It can be compared using the equality operator (==)
    • It uses the getDescribe() method to get describe result objects of a particular sObject or field
  • Describe result – contains all the describe properties for the sObject or field

Steps to Work with Describe Information

  1. Generate a list or map of tokens for the sObjects in your org
  2. Determine the sObject you need to access
  3. Generate the describe result for the sObject
  4. Generate a map of the field tokens for the sObject
  5. Generate the describe result for the field the script needs to access

describecode

Regular Expressions Matching Process

To match regular expressions using Pattern and Matcher classes, do the following:

  1. Instantiate a pattern object from the expression you wish to match
  2. Instantiate a matcher object from the pattern that contains the string you want to check
  3. Use the matcher object to detect if the matcher matches the pattern

Regularexpressionscode

Batch Apex

You can use Batch Apex to do the following:

  • Improve processing of data
  • Perform asynchronous batch processing
  • Create batch items that can be processed asynchronously due to large data volumes or complex processes
  • Build and deploy complex business processes
  • Operate over entire datasets
  • Leverage the power and flexibility of the Force.com platform

Database.Batchable

The Database.Batchable interface contains the following 3 methods:

  • Start() – called at the beginning of a batch apex job and is used to collect records or objects passed to the execute method. It will return either a Database.QueryLocator object or an iterable
  • Execute() – Is called for each batch item passed to the method. It is used to perform all required processing for each chunk of data
  • Finish() – Is called after all batches are processed and is used to send confirmation emails

Apex Scheduler

  • Schedule an Apex process such as data cleansing
  • Set a date window and a preferred start time
  • Set a weekly or monthly reoccurrence
  • Set up to 25 active schedule
  • Review the schedule status

Apex Class Notes – Receiving and Sending Emails Through Apex

The following is a portion of the notes that I took while viewing the Apex Training class, which is part of the Spring 2013 Premier Online Training available from Salesforce. This training class is one of the recommended training courses needed to complete the Salesforce Force.com Advanced Developer certification. Go here to get a PDF copy of the entire class notes.

Inbound Email Services

  • Automated process that uses Apex classes to process the content, headers and attachments from inbound emails to a salesforce.com email address.
  • Each email service has one or more salesforce-generated email addresses to which users can send a message for processing.
  • An email service only processes messages it receives at one of it’s addresses. For example, you can create an email service that automatically creates contact records based on contact info in the email message.
  • Your organization is limited in that it can only process (1000 * number of user licenses) messages per day for all email services. Anything above that limit will be bounced, discarded or queued, depending on how the email service was configured.
  • Any target email address that is created in sandbox cannot be deployed to a production org

Setting up Inbound Services

  1. Create the email handler class shell – Basically this is a global class that implements the Messaging.InboundEmailHandler class. You can view a template for creating this class by going to Setup -> Develop -> Email Services
  2. Configure an email service – Click Setup -> Develop -> Email Services -> New Email Service. From here, you enter an Email Service Name, the name of the class you created in step 1, and a type of attachment that will be accepted. You can also specify advanced email security settings to verify the legitimacy of the sending server (such as SPF, SenderId, and DomainKeys)
  3. Complete the email handler class – Will include the following Messaging objects
    • InboundEmail – contains the following:
      •  fromAddress
      •  toAddress
      •  Subject
      •  htmlBody
      • plainTextBody
      •  binaryAttachments
      •  textAttachments
    • InboundEmailResult – returns the result of the email service and sets the success flag in the exception handler class to true if the email delivery was successful
    • InboundEnvelope – stores the envelope or header info associated with the inbound email
    • Handling Attachments – notice that it handles text and binary attachments differently, thus they have to be processed in separate loops.

    EmailCode

    1. Configure failure response settings – Determine how the service responds when an attempt to access the email service fails. Some of the actions include the following:
      • Over Email Rate Limit Action – If the limits for all services has reached the daily limit of 1000 * # of user licenses/day
      • Deactivated Email Address Action – If the email address is invalid
      • Deactivated Email Service Action – If the service is inactive
      • Unauthenticated Sender Action – If the authenticated sender checkbox is selected and it fails to authenticate
      • Unauthorized Sender Action – If the users are not listed in the Accept Email From text box
      • Bounce Message – Returns message to sender with a reason for the rejection
      • Discard Message – Deletes the message and does not notify the sender
      • Requeue Message – queues the message for processing in next 24 hours
    2. Generate target email addresses – to do this, do the following:
      1. Click the New Email Address button that opens up the Email Address Information window.
      2. Each salesforce email address is case-sensitive and you only need to specify the local part of the email address, since salesforce will assign the domain name part of the address.
      3. You need to specify a context user that the Apex class will run as
      4. You can also include a list of authorized domains or complete email addresses from where emails can be accepted
    3. Activate service email addresses
    4. Test inbound email

    Email Logs

    • Are csv files that can be accessed by clicking setup -> Monitoring -> Email Log Files. The logs contain the emails sent/received through salesforce along with the email addresses, date/time, delivery status and error codes.
    • Since developers do not have access to system log files in the context of an inbound email class, they may want to create a custom object to log any exceptions or debug statements.

    Outbound Email Services

      • Emails can be written in plain test or HTML format
      • The Messaging.sendEmail method is used to send emails (can send single or mass emails)
      • Email templates can be references to reuse functionalities
      • Visualforce pages used as templates provide more template flexibility that the standard email templates
      • sendEmail method returns a sendEmailResult object. This contains two properties:
        • isSucess, which tells whether the email was accepted
        • sendEmailError , which is a list that contains field names, the text of the error message, status codes, and the ID of the target record

    Features of Outbound Emails

        • Org Limits on the number of sendEmail calls include:
          • No more than 10 sendEmails methods for each context
          • All single and mass emails sent from Apex count against the daily mass mail limit and when it is reached, all calls are rejected
        • There are separate limits for emails sent using workflow and approval–related processes, which include:
          • No more than 1000 email alerts per license/per org
          • Daily email limit for overall org is 2 million and when reached, a warning email is sent to default workflow user and system admin
        • No more than 1000 emails can be sent to external email addresses/day
        • There is no limit to the number of internal emails that can be received

    Email Security

      • Emails from Salesforce can be configured to automatically comply with SPF and SenderId security frameworks
      • SPF modifies the From address of an inbound email to a Salesforce.com email address to verify it’s legitimacy
      • Enable SenderId compliance to automatically populate the sender field of every email sent from Salesforce with no-reply@salesforce.com
      • The SenderId compliance enables the receiving mail servers to verify the sender of an email

Lessons Learned While Writing Apex Code

I have been writing object-oriented code for several years and specifically writing Apex code for over a year now, yet every time I go to create a new class or a trigger, I feel like I learn something brand new. This post is a summary of some of the most important lessons I have learned. I hope it helps you to avoid some of the same speed bumps that I have encountered.

Tip #1 – Make sure you “Bulkify” every Trigger

This is “THE BIGGEST TIP”. It is probably the one you will see the most written about, but it is so critical to writing good code, that I think it is ok to re-stress the point. In case you do not know, bulkifying a trigger means that the trigger can effectively handle being executed numerous times (200 times typically). trigger

Why 200?

Well that is usually the maximum number of times it can be executed (depending on the context). You see, your trigger can be executed multiple ways. It can be executed by users performing actions in Salesforce, or it can be executed by someone bulk loading data through the Apex Data Loader or the API. If your code is not written efficiently, it could very well throw the dreaded “Too Many SOQL Queries”. Trust me, you do not want to see this message.

So how do you avoid it?

Glad you asked. I am not going to bore you with a long detailed explanation of what you can do to bulkify your triggers, because honestly that has been done to death. I will however, tell you the golden rule to remember when writing triggers:

“If any of the following statements (SELECT,UPDATE, INSERT,DELETE) appear within a for loop, your code needs work.”

Basically, if any of those statements (which represent either a SOQL Query or a DML statement) appears in a for loop, this means you are executing a very expensive operation numerous times (or at least as many times as the loop iterates, perhaps even more). Avoiding expensive database calls is a common thing to avoid in any programming language, but is especially important for Apex development because of Salesforce’s Governor Limits (which imho are GREAT for ensuring that we all create the best code possible).

If you want to learn more about all the things you can do to bulkify your triggers, check out this very informative post by Salesforce Guru, Jeff Douglas. Everyone should also checkout the post on the DeveloperForce Wiki titled, “Apex Code Best Practices“.

Tip #2 – Create at least two testMethods in your Unit Test Code

Most posts or instructions I read did not really stress the importance of creating both a single instance and bulk instance testMethod in your test class.

Why two methods and not just one?

The first method should be for testing what happens when a single record is handled. It is here that you should include System.AssertEquals to test whether a condition is true. This will tell you whether the trigger actually did what it was supposed to do.

It is possible to write Unit Test code that does not do this kind of check and still get 100% coverage. However, I would not consider the test to be a good one and neither should you.

The second test method should cover what happens when the trigger must handle multiple records. The following code is an example of using two such methods to test the validity of a trigger.

TestBulkCode

Tip #3 – Bulkifying your code is not just important for triggers

So what else is it important for?

How about Unit test code contained in class files – especially the ones that were built while keeping tip #2 in mind. That’s right, even your unit test code needs to be written efficiently – especially when it is set to execute a bulk testMethod.

If your Unit Test code uses a For loop to create a set of records and performs a SOQL query or a DML statement within that loop, guess what? Not only might you get an error, but your code is going to take way longer than it should to run tests and ultimately deploy.

This tip also applies to methods contained within a Helper class. The more efficient your code, the better, so always assume the worst and expect all of your code to be called multiple times.

Tip #4 – Use Both the Developer Console AND the Force.com IDE

I have been very impressed with the newly available Developers Console. For a long time, the Force.com IDE was hands down the best tool for developing Apex code, but I feel like that is starting to shift – a bit, at least.

For some tasks, I prefer using the Force.com IDE – like for just browsing and editing code. I also love the schema editor for examining metadata. However, I am discovering that there are certain tasks that I prefer the Developer Console for.

The biggest thing is for running Unit Tests. In my experience, the Developer Console is many times faster at executing unit tests – especially the ones that test bulk methods.

I also like the way the execute anonymous code area is right at the top of the Console. It just makes more sense to me in this spot. I also like the layout of the Query Editor tab and especially that it returns the value of an AggregateResult (see image below). This is something you cannot do with a query in the Schema Editor of the Force.com IDE

DeveloperConsole

If you have not checked out the Developer Console or only glanced at it, I encourage you to give it a look. Try doing some tasks in one tool and then switch to doing the same task in the other tool. You may be surprised by which you prefer.

Tip #5 – Periodically go back and evaluate old code

Just like no two people will likely write the same identical answer to an essay test, no two developers will write the same development code (unless of course, you copy someone else’s code). There are dozens, maybe hundreds of ways to code some things and most ways involve inefficient code. Chances are high that you have written at least one piece of code that can be improved.

Learning how to be an efficient developer is a process. You do not learn it by reading one article, one book, or one post. It takes time to develop the skills to write efficient code in every situation – especially when you are new to a platform or language. Set aside time (say once a year) to periodically go back and evaluate old code you have written. You will probably be surprised at how much you can learn in a year.

Apex Class Notes – Working with Web Services

The following is a portion of the notes that I took while viewing the Apex Training class, which is part of the Spring 2013 Premier Online Training available from Salesforce. This training class is one of the recommended training courses needed to complete the Salesforce Force.com Advanced Developer certification. Go here to get a PDF copy of the entire class notes.

Custom Web Services

  • The webservice keyword allows developers to create their own SOAP Web Services and defines methods that are inherently global
  • Two ways to invoke Web Services:
    • From the AJAX toolkit by importing the apex.js library and call the execute method
    • From a client program by importing the WSDL and calling the custom method directly
  • Access WSDL support through Setup -> Develop -> Classes

Guidelines for Creating Custom Web Services

  • Must be static and cannot be overloaded
  • Method signatures cannot include exceptions, maps, sets, matchers, or patterns
  • Webservice keyword cannot be used in any code contained in a trigger
  •  A SOAP request or response cannot be bigger than 3MB
  • The max size of the a SOAP request/response is regulated by the governor limit
  • Webservice methods execute as System by default and can be changed with the “with sharing” keyword.
  • @ReadOnly annotation can be used with web services to allow unrestricted queries when no DML operations are necessary.

SOAP Web Service Callouts

  • Web services are called from external sources using SOAP Web Service Callouts
  • Functionality is grouped based on business processes and is packaged as interoperable services.
  • Functions are separated into distinct units or services, which are available over the network so that these can be combined and reused to produce business applications.
  • External Web Services can be called natively from Apex by using SOAP Web Service Callouts

WSDL Support and Limitations

  • Apex supports a limited set of WSDL schema types. It also supports the element and sequence WSDL schema constructs, as well as Blob, decimal and enum for call ins, but not for call outs.
  • Apex does NOT support encoded services
  • It also does not support WSD files with multiple portTypes, multiple services, or multiple bindings.
  • WSDL files with imports are NOT supported
  • It may be necessary to do a standard HTTP callout using a web services API such as RESTful web Services API.

HTTP Headers

  • Can be set on a web service callout to set the value of a cookie in an authorization header.
  • Can add inputHttpHeaders_x and outputHttpHeaders_c to an instance of your generated WSDL class.
  • inputHttpHeaders is used to set authorization or cookie information
  • outputHttpHeaders can be used to read the HTTP response headers returned after an HTTP request

Client Certificates

  • Developers can send a client certificate with their callout to authenticate an HTTPS connection with a specified value.
  • You can download a certificate through setup -> Security Controls -> Certificate and Key Management
  • Create either a self-signed or CA-signed certificate
  • Import the certificate on the remote application server that is being contacted as part of Web Service Integration
  • You can also use Setup -> Developer -> API -> Generate Client Certificate to generate a client certificate for inbound calls, but not outbound ones.

Runtime Callout Considerations

  • Request/Response must be no more than 3MB
  • A short duration custom timeout can be defined
  • A single Apex transaction can make a maximum of 10 callouts with a total request time of 120 seconds
  • A circular reference can occur between Apex methods
  • More than one loopback connections to Salesforce are not allowed
  • To allow an endpoint to be accessed, it should be registered in Setup -> Security Controls -> Remote Site Settings. This is also known as whitelisting an endpoint, which tells Salesforce that it is ok to accept requests from this site.

Invoke an Imported web Service

  • Successful importation of an external WSDL will generate an Apex stub (proxy) class
  • Use the stub instance to setup your authorization credentials for the external service
  • Use the stub to make external service method calls

RESTful Service Callouts

  • Stands for Representational State Transfer
  • Builds on the existing structure of the web by using HTTP verbs such as POST, GET, PUT, and DELETE
  • A RESTFul service is called by hitting the resource URL, which can be pasted directly into a web browser (must be one line with no breaks).
  • Simply sends and receives XML or JSON (Javascript Object Notation) data over HTTP
  • Apex provides helper classes to parse and render XML and JSON data structures

XML Classes

  • Callouts can be made from Apex where WSDL is not imported
  • External web services can be accessed using HTTP callouts
  • Send HTTP requests such as GET, POST, and PUT and also handle responses returned by request
  • The XML Stream classes provide methods that make it easy to read and write XML strings
  • XMLStreamReader class is used to read through XML responses returned from callouts and enables forward, read-only access to XML data returned from an HTTP callout
  • XMLStreamWriter class is used to create an XML document and enables the writing of XML data.
  • Document and XMLNode classes can be used as an alternative to XML classes

JSON Classes

  • The JSON class provides methods to serialize and deserialize JSON content
  • JSONGenerator class is used to serialize Apex objects into JSON content and enables the generation of standard JSON-encoded content
  • JSONParser class is a parser for JSON-encoded content. It is used to parse a response that’s returned from a call to an external service that is in JSON format

Classes to make RESTful callouts

  • HTTP class is used to sned an HTTPRequest and receive an HTTPResponse. It has only one method, send(), which takes one HTTPRequest argument and returns an HTTPResponse
  • HTTPRequest class is used to programmatically create HTTP requests. It has several methods, such as:
    • setEndpoint
    • setBody
    • setHeader
    • setMethod
    • setClientCertificate
    • getEndpoint
    • getBody
    • getHeader
    • getMethod
  • HTTPResponse class is used to programtically handle the HTTP response returned by HTTP. It has several methods, such as:
    • getStatus
    • getStatusCode
    • getHeader
    • getHeaderKeys
    • getBody
    • getXMLStreamReader

RESTful Callout Example

public class HttpCalloutSample {
//pass in the endpoint to be used using the string url
public String getContent(String url) {

     //Instantiate a new HTTP object
Http h = new Http();

     //Instantiate a new Http request, specify the method (GET) as well as the endpoint
HttpRequest req = new HttpRequest();
req.setEndpoint(url);
req.setMethod(‘GET’);
//Send the request and return a response
HttpResponse res = h.send(req);
Return res.getBody();
}
}

HTTP Helper Classes

  • EncodingUtil class helps to encode and decode URL strings and includes the following methods:
    • Base64Decode – converts a Base64-encoded String to a Blob
    • Base64Encode – converts a Blob to an un-encoded string
    • convertToHex – returns a hexadecimal (base 16) representation of the input string
    • urlDecode – decodes a string using “UTF-8”
    • urlEncode – encodes a string
  • Cryto class enables access to external services that require encryption and includes the following:
    • Encypt – encrypts the blob clearText using the specified algorithm. Use when you want to specify your own initialization vector
    • Decrypt – decrypts the blob cipherText using the specified algorithm
    • Sign – computes a unique digital signature for the input string using the supplied private key and the specified algorithm. This method supports the RSA-SHA1 or RSA algorithm
    • generateMAC – computes a message authentication code or MAC for the input string using the private key and specified algorithm. Supports the HmacSHA1 algorithm
    • generateDigest – computes a secure, one-way hash digest based on the supplied input string and algorithm name. Supports algorithms such as Md5 and SHA1
    • generateAESKey – generates an Advanced Encryption Standard (AES) key. You can size to specify the keys size in bits

    Apex REST-based Web Services

    • You can implement custom web services in Apex and expose them through the REST architecture by using Apex REST.
    • To do this, you first define your class with @RestResource annotation to expose it as a REST web service
    • You also annotate methods to be exposed with the appropriate HTTP method. The following methods are available:
      • HttpDelete
      • HttpGet
      • HttpPatch
      • HttpPost
      • HttpPut
    • You must define your methods as global static. For example:

    @RestResource (urlMapping=’/contact/v1/*’)
    global class MyRESTService {
    @httpPost
    Global static Id doPost (String cLastName, Account a) {
    Contact c = new Contact(LastName = cLastName, AccountId = a.Id);
    Insert c;
    Return c.id;
    }
    }

    Additional Apex Support for REST Web Services

    • RestContext object contains the RestRequest and RestResponse objects
    • Methods with @HttpGet or @HttpDelete annotations should have no parameters
    • Use user-defined types for parameters in Apex REST methods
    • JSON and XML formats are used to represent resources

    Using REST-based web Services

    • You can invoke a REST-based web service through an appropriate HTTP request and a URL, which includes a location of the Salesforce server, an Apex REST service, and a resource.
    • It is best to try and find an exact match. If you cannot find an exact match, then find all the patterns with wildcards that match, and then select the longest of those by string length. If you cannot find a wildcard match, then an HTTP response status code 404 will be returned.

    Asynchronous Apex

    • If any Apex process takes more than 5 seconds, you should consider moving it to asynchronous Apex.
    • To identify methods that are asynchronously executed, use the @future annotation. These must be static and can only return a void type
    • Use the @future annotation to make a web services callout from a trigger
    • A max of 10 method calls per Apex invocation are allowed
    • A max of 200 @future method calls per Salesforce license per 24 hours are allowed
    • The parameters passed to an asynchronous method must be primitive datatypes
    • Methods with the @future annotation cannot be used in getter/setter methods or constructors of Visualforce controllers
    • The asynchronous Apex code starts a new governor limit transaction context when it is run.
    • When you use a trigger to call an external service; that service needs to support batch processing similar to Force.com API; otherwise making 1 callout per record in a bulk trigger will quickly exceed governor limits

Apex Class Notes – Deploying Apex Code

The following is a portion of the notes that I took while viewing the Apex Training class, which is part of the Spring 2013 Premier Online Training available from Salesforce. This training class is one of the recommended training courses needed to complete the Salesforce Force.com Advanced Developer certification. Go here to get a PDF copy of the entire class notes.

Deployment Process – Steps are as follows:

1.)    Develop

  1. Develop
  2. Unit Test
  3. Begin Integration Testing

2.)    Integrate

  1. Software modules are tested as a group
  2. Integration testing may be done in another sandbox and is done before functional and acceptance testing

3.)    Stage

  1. Full regression testing
  2. Load Testing
  3. Specific new feature testing
  4. User acceptance testing

4.)    Production/Training

  1. After changes are accepted, change control board approves deployment in production and/or training

Prerequisites for Deployment

  • Some components such as queues, time triggers and time-based workflows are not 100% covered by the Metadata API and must be deployed manually
  • When org specific data needs to be deployed, you can switch to work-offline mode and remove the org-specific information from the metadata and deploy that to the production org.

Types of Deployment

  • Force.com IDE
    • Right-click the project and select Force.com and Deploy to Server
    • Enter Username, password and environment.
    • Select Destination Archive since this will allow you to rollback if necessary
    • In the Deployment List, new items are displayed in green and items found in both the local repository and target org that have changed are in yellow. Items found in target but not the local repository is in red and can be deleted. Everything else is in grey and not selected by default. From here you select what is to be deployed.
    • You can also click to “Validate the Deployment”
    • If there are any issues, you will have to fix them before continuing
    • The log allows you to send as an email
    • If there are no issues, you get a Success and you can then Deploy
  • Force.com Migration Tool
    • Ant-based command line tool for people that prefer scripts.
    • The Build.properties file contains the login details
    • The build.xml file includes the build.properties file and enables developers to override default values
    • Deploy and Retrieve are customized tasks used to create, update and get metadata
    • The deployment script can be executed as part of a batch file from the command shell. This is done by running Ant, followed by the name of the target from the directory where build.xml exists.
  • Change sets for related orgs
  • Third-party tools such as Dreamfactory Snapshot for non-technical IT users

Apex Class Notes – Exceptions, Debugging and Testing

The following is a portion of the notes that I took while viewing the Apex Training class, which is part of the Spring 2013 Premier Online Training available from Salesforce. This training class is one of the recommended training courses needed to complete the Salesforce Force.com Advanced Developer certification. Go here to get a PDF copy of the entire class notes.

Exceptions

  • Records information about the error, the type of error and the state of the script or program when the error occurred
  • Exceptions can be handled using the following keywords:
    • Throw
    • Try
    • Catch
    • Finally (optional)
  • Syntax Example:

Try {
Update positions;
}
Catch (System.DmlException e)  {
System.debug(‘DML Exception: ‘ + e.getDmlMessage(0));
}
Finally {
Positions.clear();
}

Exception Types

  • System-defined Classes
    • ListException
    • DmlException
    • MathException
    • NullPointerException
    • QueryException
    • SecurityException
    • SobjectException
    • StringException
    • TypeException
  • User-defined Classes – created only if the system-defined exceptions do not offer required behavior
    • Must end with the string Exception
    • Must extend the system-defined Exception class
    • Is a catch-all type of class
    • Should be placed at the end of all catch blocks
    • Example:

Public class MyCustomException extends Exception {}
Contact con = new Contact(LastName = ‘ContactLastname’);
Try {
Insert con;
} catch (DMLException e) {
Throw new MyCustomException(‘Could not create a contact ‘, e);
} finally   {
System.debug(‘Tried to create a contact’);
}

System-Defined Exception Methods

  • getMessage – returns message displayed to user
  • getTypeName
  • initCause(sObject Exception) – sets the cause if it is not set already
  • getCause() – returns cause as an Exception object
  • Methods that have DML in their name are only supported for DML exceptions. They are:
    • getDmlFields(int) – returns names of the field(s) caused by the ith failed row
    • getDmlIndex(int) – returns the original row position of the ith failed row
    • getDmlMessage(int) – returns the user message for the ith failed row
    • getDmlStatusCode(int) – returns the failure code for the ith failed row
    • getNumDml – returns the number of the failed row

    Debugging

    • Two primary tools:
      • Logs – such as the Developer console or the Debug Logs
      • Anonymous Blocks – useful ad-hoc tool to execute code through the Force.com IDE

      System Logs

      • Can be viewed in the Salesforce UI or the IDE
      • Is limited to 2MB per log
      • Each org can retain up to 50MB of logs
      • Log Filters:
        • Database – log messages generated by calls to System.debug, DML Statements, or SOQL and SOSL queries
        • Workflow – Info about workflow, assignment, auto-response, escalation rules
        • Validation – Info about validation rules
        • Callout – XML sent through web services
        • Apex code – Info about Apex scripts, DML statements and queries, triggers and total resources used
        • Apex profiling – Cumulative profiling info
        • Visualforce – Info about Visualforce events
        • System – Info about calls to all system methods
      • System Log Levels:
        • Error, Warm and Info
        • Debug – calls to System.debug
        • Fine, Finer – Includes calls to system.debug, every DML statement or inline query and entrance and exit for every user-defined procedure.
        • Finest – Includes everything at fine or finer and addition info, such as variables declared, start of loops, thrown exceptions, static and class initialization and changes in sharing context.
      • Debug Log Filters – You can raise the log levels for specific classes when debugging, as well as turn off logging for other classes. All classes and triggers inherit the settings from their caller unless overridden.
      • Debug logs capture the same info as the system logs. You can get to them by going to Setup -> Monitoring -> Debug Logs. They are specific for a user

      Anonymous Blocks

      • Does not get stored and executes under the context of the current user. Primarily used to debug code on the fly, but it cannot include the static keyword.
      • Can be executed one of 3 ways:
        • Using the executeAnonymous() Web Services API call
        • Developer Console within Salesforce
        • Force.com IDE

        Unit Testing

        • Do not take arguments and do not commit data to the DB.
        • Two ways to create:
          • Using the TestMethod keyword
          • Using the @isTest annotation
        • The IDE has a template for creating Unit Test classes
        • Governor limits are applied to unit tests
        • Use the startTest and stopTest system static methods with testMethod to test governor limits.
        • These methods may only be called once within each testMethod.
        • Insert the startTest method after all of the test infrastructure has been set and just prior to the actual methods to be tested
        • Unit tests can be run through a call to the runTests method.
        • The compileClasses and compileTriggers methods can be used to just compile code without testing to verify the syntax
        • Ways to run Unit tests:
          • From the Salesforce UI for all classes – Go to Setup -> Develop -> Apex Classes and click “Run All Tests” button.
          • From the Salesforce UI for one class – First select the class and click the “Run Test” button.
          • In the Force.com IDE – Right-click a class, select Force.com and Run Test. Better to run unit tests from here.
          • From the runTests() web service method
        • Best Practices:
          • Use System.Asset() method to verify results
          • Do not assume that record ID’s are in sequential order and use the ORDER BY keyword to ensure that records are returned in expected order.
          • Make sure that code can handle more than 200 records
          • Use System.Runas() to test record sharing
Follow

Get every new post delivered to your Inbox.