The Silver Lining

A developer's view of Cloud Computing platforms & technologies.

Salesforce: Universal Batch Scheduling Class

with one comment

Mark David Josue. All Rights Reserved.I’d like to propose a new way of working with scheduled batch classes. I’ve worked on several hundred Salesforce projects in the past few years and often see batch scheduling classes being created per scheduling requirement and it grinds my OCD – not in a good way. In most cases you should only need one “Batch Scheduler” per Org, let me demonstrate how and why.

The Universal Batch Scheduler™

Requirements

Let’s assuming you have a batch class that you need to run on a repeated schedule*, such a class signature is given below. That class will have to obey some conventions such as implementing the Batchable interface as shown in the standard documentation.

global class MyBatch implements Database.Batchable<SObject> {

// …

}

* For one off, schedule execution of batch classes you can use the System.ScheduleBatch() method.

The Scheduler

Now you might be tempted to created a scheduled Apex class specifically for this batch class, but by using the principle of polymorphism you could create a universal scheduler instead.

First of all you’ll need to implement the required interface for scheduled Apex classes as shown below.

global class BatchScheduler implements Schedulable {

// …

}

Next assign global, class-level variables which will be used to access the parameter values required when executing a batch class. Note that we’re creating a variable called “batchClass” whose type is the interface Database.Batchable. This means that any class that implements this interface can be assigned to this variable, this behaviour is called polymorphism.

  global Database.Batchable<SObject> batchClass{get;set;}
  global Integer batchSize{get;set;} {batchSize = 200;}

And finally implement the method required by the Scheduleable interface and use the variables to kick off the execution of a batch class.

  global void execute(SchedulableContext sc) {
   database.executebatch(batchClass, batchSize);
  }

Et voila! You now have a class that can be used to schedule any batch class in your Org. The final code being:

global class BatchScheduler implements Schedulable {
  global Database.Batchable<SObject> batchClass{get;set;}
  global Integer batchSize{get;set;} {batchSize = 200;}

  global void execute(SchedulableContext sc) {
   database.executebatch(batchClass, batchSize);
  }
}

In order to use it you would have to initiate the schedule from an anonymous block (Developer Console, Eclipse, Mavensmate etc.). For example I would schedule my batch class using something like this:

// Instantiate the batch class
MyBatch myBatch = new MyBatch();

// Instantiate the scheduler
BatchScheduler scheduler = new BatchScheduler();

// Assign the batch class to the variable within the scheduler
scheduler.batchClass = myBatch;

// Run every day at 1pm
String sch = '0 0 13 * * ?';

System.schedule('MyBatch - Everyday at 1pm', sch, scheduler);

There may be cases where the universal batch scheduler is not appropriate i.e. special pre-work has to be done in the scheduling class, but in most cases I’ve seen it’ll do the job. Hopefully this’ll help you make your Orgs a little neater too.

Written by Wes

February 2, 2014 at 12:34 pm

If This Then Salesforce

leave a comment »

I’ve been enjoying IFTTT for a while now and if you haven’t experimented with it yet then I’m not sure we’ll ever be friends. Essentially it’s a very easy tool that lets you set triggers on a source API e.g. Foursquare and have some information from that API be posted to a target API e.g. Jawbone Up. IFTTT calls these recipes and I’d like to demonstrate some particularly delicious combinations that can be used with Chatter.

Salesforce Org Alerts and Known Issue posted to Chatter

Salesforce makes Instance Alerts e.g. “Perfomance degradation on EU0.” available through an RSS feed so all you need to do is create a recipe (or copy mine) that monitors the appropriate RSS url for changes and posts to a particular Chatter group.

You can do a similar thing with Salesforce Known Issues.

Tweets posted to Chatter

Quite often there are interesting tweets that I want to share with a particular group on Chatter. One of the recipes I’ve created in this class uses the hashtag #tqcd to push a particular tweet to our “Development” Chatter group.

Screen Shot 2013-11-15 at 15.24.04We also have more than a few Reid Carlberg fans in Tquila so we have a recipe that shares his tweets to a dedicated group in our Org. His tweets are mostly about facial hair at the moment but who am I to judge genius.

Limitations

At this point Chatter can only be used as a target system in any recipe but I’m hoping they’ll change that in future.

Best Practices

So far I’ve established two guidelines:

  • Create a separate Chatter group for recipes that will be executed often. This gives people the option to opt-out of those posts.
  • If possible create a separate Salesforce user to post on Chatter. This will reduce the number of explicit posts you making it easier for others to find information in your feed.

You can find all these recipes on my IFTT profile. There are quite a few other interesting recipes regarding Salesforce on the IFTTT website but I’m hoping that you’ll be inspired to think of new creative ways to use the tool. If you do please let me know in a comment below or on Twitter.

Written by Wes

November 15, 2013 at 5:35 pm

Salesforce Analytics API Sample Code

with 4 comments

Spider ChartA picture is worth a thousand words, so goes the justification for graphic novels. I kid, I love the hell out of graphic novels but now I’ve been sidetracked and this is only the second sentence of this post.

So, the Analytics API. I’m pretty enamoured with it as it seems is Pat Patterson, and I think that it’s one of the most useful features the platform has ever made available. Presenting the right chart (or set of charts) to a manager or executive can empower them to make business decision in minutes, powerful stuff. To that end myself and a few of my fellow Tquilites have begun building an opensource library of Analytics API demos to aid you in aiding your clients/managers/execs.

Below I’ve included a few introductory steps to help you get started. To start with you’ll need the code from github.

Step 0

I’ll be stepping through the Google Charts Stacked Bar Chart example from github so you’ll be able to test this out yourself.

Step 1 – Create a report

Certain report formats map well to certain chart formats so make sure you choose the right type of report. For example, stacked bar charts map well to matrix reports, summary charts map well to pie charts.

Once you have created your report and have some interesting data, determine the report ID and keep it somewhere safe. Report IDs always start with “00O”.

Report ID

Step 2 – Create a Visualforce Page

As it says in the heading of this section, create a new VF page. Easy peasy lemon squeezy.

Step 3 – Include the chosen JS library

As with any web-based language you’ll need to include the JS library that you want to use. I’m going to use Google Charts in this example. Note I’m also using jQuery to make the AJAX callout.

 <script type=”text/javascript” src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
 <script type="text/javascript" src="https://www.google.com/jsapi"></script>

Step 4 – Call the Analytics API

The API call can be made server-side or client-side, with this example making use of a client-side call.

    /** Fetch the JSON data representing the the report **/
    var jsonData = JSON.parse($.ajax({
        beforeSend: function(xhr) {
          xhr.setRequestHeader('Authorization', 'Bearer {!$Api.Session_ID}');
        },
        /** You'll need a URL parameter key called "id" that has a Summary Report id value **/
        url: "/services/data/v29.0/analytics/reports/{!$CurrentPage.parameters.id}",
        dataType:"json",
        async: false
        }).responseText);

The results of the callout are fed into the callback function and available through the variables “ai” and “ae” (see below).

Step 5 – Parse the resulting JSON & build the required data structure

The structure of the JSON depends on the report type but is fairly simple to understand. Be sure to use console.log() to investigate what’s going on if you get stuck.

    var chartData = new google.visualization.DataTable();

    chartData.addColumn('string', 'Stage');

    $.each(jsonData.groupingsDown.groupings, function(di, de) {
      chartData.addColumn('number', de.label);
    });

    $.each(jsonData.groupingsAcross.groupings, function(ai, ae) {
      var values = [];
      values.push(ae.label);

      $.each(jsonData.groupingsDown.groupings, function(di, de) {

        values.push(jsonData.factMap[de.key+"!"+ae.key].aggregates[0].value);
      });

      chartData.addRow(values);
    });

Step 6 – Generate the chart

Finally invoke the drawing of the chart along with any options required.

    var options = {
      title: jsonData.attributes.reportName,
      vAxis: {title: jsonData.reportMetadata.groupingsAcross[0].name},
      isStacked: true
    };

    var chart = new google.visualization.ColumnChart(document.getElementById('chart'));
    chart.draw(chartData, options);

Voila! You now know the basics of building custom charts in Visualforce (or any other web language) using the Analytics API. To try this out log into your Org and then browse to:

http://[your salesforce instance]/apex/YourPage?id=[reportId]

Feel free to use this code anyway that you can imagine and we’d be over the moon if you contribute your own awesome to what we’re building. Fork us on github.

Written by Wes

November 10, 2013 at 4:57 pm

Developing Chrome Extensions for Salesforce

with 4 comments

Get off my case!Chrome extensions are awesome, they provide amazing convenience that is limited only by your imagination. There are some amazing Chrome Extensions for Salesforce already, some of my favourites being:

As a great fan of JavaScript I’ve always wanted to create a Chrome Extension for Salesforce and I’ve finally gotten around to it. The hardest part was figuring out what context the JS executes in (e.g. in the current tabs context, or in some separate context). Let me step through the code to show you how it’s done.

Chrome Extension Structure

A Chrome Extension is made up of a JavaScript, HTML, images and JSON. At its core is a manifest file which contains the metadata describing your application in JSON. There is a lot of documentation about the structure of this file but some of the key elements are shown below.

{
  "name": "Get off my case!",
  "version": "0.8.1",
  "description": "Presents a notification above the favicon with the number of cases assigned to the current user.",
  "manifest_version": 2,
  "icons" : {
               "16": "img/icons/16.png",
               "48": "img/icons/48.png",
               "128": "img/icons/128.png"
             },
  "permissions": [ "tabs", "https://*.force.com/*", "https://*.salesforce.com/*"],
  "update_url": "https://clients2.google.com/service/update2/crx",
  "author": "Wesley Nolte",
  "browser_action": {
     "default_icon": "img/tquila_lozenge.png"
  },
  "content_scripts": [ {
     "js": [  "js/jquery.js",
              "js/forcetk.js",
              "js/tinycon.js",
              "js/contentscript.js" ],
     "matches": [ "https://*.salesforce.com/*", "https://*.force.com/*" ]
  }]
}

This file references all external resources (JavaScript, images etc.), the important parts here being the JavaScript i.e. jquery.js, forcetk.js, tinycon.js and contentscript.js. In short these files represent:

  • jquery.js – the jQuery library
  • forcetk.js – the JavaScript wrapper for the Salesforce.com REST API, but with one modification i.e. the ability to fetch info about the current user
  • tinycon.js – a small library used to create the notification on the tab
  • contentscript.js – the JavaScript file that brings them all together

The JavaScript

The first 3 JavaScript files are libraries that great, but aren’t particularly interesting in the context of this tutorial. The last file is where the magic happens, the code is listed below.

/* Get the cookie values om nom nom */
function getValueFromCookie(b) {
    var a, c, d, e = document.cookie.split(";");
    for (a = 0; a < e.length; a++)
        if (c = e[a].substr(0, e[a].indexOf("=")), d = e[a].substr(e[a].indexOf("=") + 1), c = c.replace(/^\s+|\s+$/g, ""), c == b) return unescape(d)
}

/* Encapsulating code instead of just letting it lay about */
function init() {
	// Get an instance of the REST API client and set the session ID
	var client = new forcetk.Client();
	client.setSessionToken(getValueFromCookie("sid"));

	// Retrieve the data representing the current user
	client.currentUser(function(response){
		var user = response;

		// Find cases that belong to the current user
		client.query("SELECT COUNT() FROM Case WHERE ownerId = '{0}'".replace("{0}",user.id), function(response){
			Tinycon.setBubble(response.totalSize);
		});
	});
}

init();

In short the code gets the session ID from the user’s cookie (the extension works in the context of the current user session for that tab) and uses that to call in using the REST API. Pretty easy huh?

Sourcecode and Extension Install

The sourcecode is on github if you want to experiment with it, and if you’d like to see it in action you can install it from the Chrome Web Store.

Written by Wes

September 14, 2013 at 1:26 pm

Salesforce: Files vs CRM Content vs Knowledge vs Documents vs Attachments

leave a comment »

The MatrixChoosing the right file or document management system on- (or off-) platform can be a difficult decision, and one of those things that’s difficult to change once implemented so it’s important to make the right choice up front.

Salesforce.com has a number of content and document solutions (and more on the way) and the options when given a set of decision points aren’t always clear. To this end I’ve created a matrix comparing the on-platform systems which should make that decision easier. It’s based on the official documentation but add in a few other key decision points (please don’t sue me Salesforce, I’m just a lowly a certified technical architect!).

If I’ve got anything wrong, or left something out please let me know.

Written by Wes

August 29, 2013 at 7:05 pm

Salesforce User License Feature Matrix

with 2 comments

Understanding Salesforce licensing is incredibly important for all areas of a business buying salesforce and implementation projects. Common questions are:

  • What licenses are available?
  • How much do they cost?
  • Which license types support my intended solution?
  • What are the limitations?
  • How are they “consumed”?

As part of my Salesforce TA Certification I created a matrix that compares all current license types making it easy to learn about licenses and make the licensing decision a bit easier. The matrix isn’t comprehensive but instead tries to balance ease-of-use whilst providing the most important decision points.

Let me know if I missed anything important!

References

Written by Wes

August 10, 2013 at 12:25 pm

Posted in SalesForce

Tagged with ,

Salesforce Certified Technical Architect

with 3 comments

Fall seven times, stand up eight.

- Japanese proverb

Finally, I have this certification. This has been a journey for me, and taken much longer than I anticipated. I did fail the first attempt, but was given a retry (make-up exam) in the sections that I’d failed. I subsequently failed that too. My second, full attempt saw me pass, and in fact I found it quite easy so let me help you learn from my mistakes.

Attempt 1

Late last year I booked in my board review exam. I’m not going to go into the detail of what the board exam entails it’s because this has been discussed in detail here, here and here. I spent a lot of time preparing, and had some ad hoc coaching from the UK SFDC certification team but in the end the hypothetical exam destroyed me. Here’s why:

  • I’d been developing apps for nearly a year and was rusty with regards to various features of the platform used heavily in projects e.g. sharing, roles, content, knowledge
  • I missed the “formal coaching” that SFDC offers for those that pass the stage 2 exam, and thought I wouldn’t need it

Together these two things meant that my approach to the hypothetical, and my real-world experience were weak. I knew I’d failed 2 hours into the 4 hour board. Luckily (I suppose) I did very well in the other areas, and my case study was rock-solid so I was given a “make up” exam (2 months later) in my weakest areas.

Attempt 1.1

At this point I’d been back into consulting and oiled my rusty hinges. I also brushed up on any areas of weakness and felt quite prepared. However, the destruction this time around was even worse, I knew I’d failed in the first hour! The reasons here were:

  • I felt the hypothetical here was much more difficult
  • I focussed too much on creating the presentation, and too little on understanding the question
  • I panicked and solved problems that didn’t exist

Attempt 2

Six months after my original attempt I was back in the swing of consulting, working in every role imaginable from sales through to QA and release management. I’d also gone through the “Seed the Partner” official coaching. I honed my approach to the hypothetical and brushed up on Summer 13. And I passed. And it wasn’t that difficult, here’s why:

  • I’d gone through the official coaching with SFDC
  • I’d known the theory all along, but also had the opportunity to flex the old consulting muscles
  • I convinced myself not to panic
  • I read every word of the hypothetical at least twice, focussing on understanding instead of focussing on creating the presentation
  • I drew. I’m not very comfortable with Powerpoint as an architecting tool but for some reason felt compelled to use it in my hypothetical previously. This time around I did what I was comfortable with, telling a story backed by several diagrams drawn in front of the judges as I presented.

I’ve also developed several assets that helped me to study and will be sharing them in a series of posts in the coming weeks.

- Wes Nolte, Force.com MVP, Certified SFDC TA, BBQ Master

Written by Wes

July 24, 2013 at 9:34 pm

Follow

Get every new post delivered to your Inbox.

Join 1,849 other followers

%d bloggers like this: