Pages Menu
Categories Menu

Posted by on Jul 17, 2012 in The Cloud |

Private Cloudwashing — No Innovation? Duh…

No water in the desert...

Who knew?

David Linthicum’s June 2012 post over at InfoWorldmakes an interesting argument that “innovation is in scarce supply” in cloud computing. He mentions that companies are either just copying what Amazon is doing with Amazon Web Services (Rackspace, I guess) or rebranding the same old virtualization offerings in an attempt at “private cloudwashing” — just polishing the turd of existing private virtualization offerings. I love the “private cloudwashing” term, but how surprising is it that he hasn’t found innovation in that space?

“Hey guys! I’ve looked all over the desert, and I just can’t find any water!”

So, instead of wandering around in the wasteland of “private cloud” nonsense, why not take a look at what’s happening with the real cloud:

Heroku

You want innovation? Is anybody moving faster that Heroku? A few years ago, it was a quick way to put a Ruby app on AWS without having to set up and maintain your own EC2 instances, load balancers, RDS or S3 data stores, and whatever operating system and software stack you decided to go with. Now it’s just as quick and easy to use, but you can deploy Ruby, Java, Python, Clojure, Scala, and Node.js apps on that same infrastructure, plus the ability to install Add-ons like PostgreSQL, Redis, Loggly, MongoDB, and a ton of other enterprise-grade packages at the click of a button. AWS is an amazing technology, but if you’re a developer who just wants to deploy an app, it takes some learning (and money) to put together a truly scalable and secure architecture on AWS. With Heroku, scalability and security are built right in. Your app can poke along on one one or two dynos while you’re starting out, but scale up in seconds to handle traffic when you find yourself (surprise!) on the front page of Reddit or the New York Times.

GitHub

If GitHub isn’t the most important thing to happen to software development in the last 10 years, I don’t know what is. “Social Coding”… what a concept! Before GitHub, open source software was conceptually a great thing, but in practice, it was difficult for developers to contribute to active projects, and just as difficult for project owners to solicit contributions from the community. Sure, it was easy to put your code up in Sourceforge (yes, there were competitors, but who are we kidding, everyone used Sourceforge back in the day…), and then Google Code code came along, but CVS and SVN are clunky compared to Git, and you generally had to either get permission from the project owner to commit changes or you had to send patches via email to the owner, who may or may not actually still be interested in maintaining the codebase.

Enter the Fork and the Pull Request: You have a project on GitHub. I want to change it. Great! I Fork it, I change it. My changes are public (unless I want them to be private, of course), and I can ask you to merge the changes into your project by submitting a Pull Request. We can then discuss the changes and, you can merge them in or reject them, all within the system, all with diffs right there in the web UI, and with the history documented for others to follow. No emails or patch files needed. And if you don’t want to merge my changes into your project, that’s fine too. They’re already out there for everyone to use. Or you can whine about it and get smacked down by Linus Torvalds (to be honest, it’s an honor)

And all this public infrastructure is right there ready to host your private projects too. Don’t want to mess around with setting up (and backing up) your own Source Control Management system? Great! Sign up for a private account, and GitHub is ready to go, just like any other real cloud provider.

Database.com

The biggest problem with most server-side database technologies is that if you want to build, say, a mobile app that uses them, you have to spend a ton of time writing a web-accessible API with secure authentication, and then you probably have to set up some sorts of rules about who can access what data. With Database.com, both of these problems are solved for you.

Create a table, and you already have a full RESTful API that allows you to describe the table, and create, read, update, or delete data. CRUD! Authentication is handled via the same industry-standard oAuth 2.0 that’s being used by Facebook, Twitter, LinkedIn, and countless others, and data visibility is determined by User Profiles and Roles — allowing groups of users to have different visibility and permissions with the data.

Amazon Web Services

It’s hard to out-innovate AWS because Amazon announces something new for AWS every few days. What better way to move your entire data center to the cloud? Servers, load balancers, storage with more 9s than you can count (my kids’ baby pictures could survive a nuclear strike), DNS, an auto-scaling Java app server, and more. Worried about availability and uptime, or about trusting your business to a 3rd party? Take a look at Netflix. Hosted entirely in AWS. Can you imagine how much bandwidth and storage Netflix Instant uses? Have you ever seen Netflix go down? Me either. They go down so infrequently that they pay you back when they do go down. Sure, individual AWS data centers go down from time to time, and it’s caused some massively bad publicity, but if you architect for failure, AWS provides an amazingly resilient infrastructure.

Chatter

I love Chatter. Anybody who knows me at work will not be surprised by that assertion. I’ve seen the changes it can make in an organization firsthand. Every now and again I’ll demo it to a client by having them ask me a question that I don’t know the answer to. Sometimes I get an answer back in under a minute from some random person I would never have thought to ask. The CEO of Toyota even claimed that through Chatter, the people of Salesforce “really changed my life”.

Chatter is a private social network for your company and your customers, and it’s all API accessible. Or multiple private social networks for your company. After all, it’s free. Yes, it’s a loss-leader for Salesforce.com, but the free tier is still a fantastic tool. It includes instant messaging now as well, and file sharing too.

Anyway, I agree with Mr. Linthicum on one thing, there’s not much innovation in the private cloud. It’s more of the same, just rebranded. With the public cloud, though–the real cloud–things couldn’t be more exciting.

facebooktwittergoogle_plusredditpinterestlinkedinmail Read More

Posted by on Jun 28, 2012 in Code, Mobile, The Cloud, Videos |

Painless Mobile App Development Webinar

Gartner predicts that by 2015, mobile app projects will outnumber PC app projects 4-to-1. Learn how to quickly build and efficiently maintain native mobile apps that scale on-demand by powering them with cloud technology. We presented this webinar June 2012 on “Painless Mobile App Development”.

In this webinar, we went over these items:

  • Create a cloud database for your app, one that’s automatically scalable and configured for disaster recovery, all in a matter of minutes without ever leaving your browser
  • Build a native mobile app that leverages the database’s open standards-based APIs for authentication and data persistence
  • Code and use a custom REST API for your app to encapsulate unique business logic and improve the efficiency of your app’s performance
  • Securely store data offline to support situations when the app cannot access the cloud database
facebooktwittergoogle_plusredditpinterestlinkedinmail Read More

Posted by on Apr 19, 2012 in Code, Mobile, The Cloud |

Storing Data Offline with Salesforce Mobile SDK SmartStore

Storing Data Offline with Salesforce Mobile SDK SmartStore

Say you’re writing a “hybrid” mobile app for iOS and Android using PhoneGap (“Callback” or “Cordova”) and you want to store data locally. Your choices are kind of limited. You could, for instance, use WebSQL, which has been implemented in WebKit for a while now and is available on both iOS and Android devices. If you clicked that link, though, you’ll probably notice the big scary warning that WebSQL has been deprecated…


 

It works right now, but maybe it’s not the best idea to use it if you don’t want to have to strip it out someday down the road. You also have to deal with all the data size limitations and requests to the user to allow the app to increase the database size.

So, what’s up next from the W3C if the WebSQL spec isn’t being maintained? The new spec is IndexedDB, which is a “database of records holding simple values and hierarchical objects”. Perfect! We’ll just check caniuse.com to make sure it’s supported on iOS and Android:


 

So… okay. It looks like it’s not supported yet on either. Does PhoneGap provide anything? In fact, it does, the Storage class. Which is based on WebSQL… I think you can see where I’m going here.

What do you do? Well, the Salesforce Mobile SDK for iOS and Android has implemented an ORM layer called SmartStore abstraction to SQLite, which uses FMDB on iOS and SQLCipher on Android. It’s easy to use and allows you to store data in JSON format locally and specify indexes for searching and sorting. Also, it uses native implementations of SQLite which are accessed via PhoneGap plugins so you don’t have any issues with HTML5 storage limitations or the W3C changing their mind about what web database technology everyone should standardize on.

To demonstrate SmartStore, I’ve put together a simple demo app, and posted it to Github:

https://github.com/tomgersic/SmartStoreDemo

The Sample App

Here it is running on the iPad simulator. One thing to know about SmartStore is that each database Table is called a Soup. It’s an Apple Newton thing. The Newton’s file system was based on a “Soup” store model. So here, I’ve asked the app to create a new Soup named “EggDrop” specified that I want to use just the “id” field as an index, and entered a Salesforce REST API query to be executed using the handy ForceTK library.


To start off, download the code from GitHub and open up the XCode project. If you want to start from scratch, you’ll want to install the Salesforce Mobile SDK for iOS and selected “Hybrid Force.com App” from X-Code’s New Project wizard.


Going from top to bottom:

  • Input Boxes
  • Soup Name: A “Soup” named this will be created.
  • Indexes: I’ll show how this gets represented in the data model in a bit, but you can specify JSON fields for indexing and specify a type of either “string” or “integer”.
  • REST Query: Basically any query to the Salesforce REST API. Here we’re just defaulting to pulling down my Chatter feed items. I have 3 in my feed in a dev org that we’ll pull down.
  • Buttons
  • Query SFDC: Run the REST Query, save the results to the specified Soup, and log the results to the console (on the page).
  • Query SmartStore: Query the specified Soup and log the results to the console. They should be the same results as the remote Salesforce Query.
  • Reset: Delete all the Soups that we’ve created during this session.
  • Logout: Log out of your Salesforce org.


SmartStore Soup Functions

To see how all this works, the interesting bits are in the inline.js file.

  • To register a Soup, we call registerSoup:


navigator.smartstore.registerSoup(soupName,indexes,success,error);

  • To add some records to that Soup, we call upsertSoupEntries:


navigator.smartstore.upsertSoupEntries(soupName,records, success, error);

  • To query the Soup, first we have to define a querySpec (buildAllQuerySpec just pulls all records rather than searching for specific records):


var querySpec = navigator.smartstore.buildAllQuerySpec(“id”, null, 20);


This querySpec specifies “id’ as an index, null (allow default) for the sort order, and 20 for the page size.

  • We then use that querySpec to get records back from the Soup:

       

navigator.smartstore.querySoup(soupName,querySpec, success(cursor),logError);

  • Additionally, if we want, we can delete Soups with removeSoup:


navigator.smartstore.removeSoup(record,success,error);

Running the App

When you run the app for the first time, you’ll be presented with an oAuth 2.0 User-Agent login screen for Salesforce. If you don’t already have a Developer Org, get one at http://developer.force.com/. It’s free.

Once you log in, hit Query SFDC, and you see the Soup get registered, JSON data gets downloaded from the REST API and added to the SOUP. Take a look at the JSON data, and then hit the “Query SmartStore” button. You’ll see it load that same data from the SmartStore Soup and display it in the console log.

The Database

Let’s take a look at the actual SQLite database file and see how things are stored behind the scenes. You’ll see we have 3 tables in the database: soup_names, soup_index_map, and TABLE_1 (sqlite_master and sqlite_sequence are used internally by SQLite):

 

  • soup_names keeps a list of the Soups I’ve created

 

 

  • soup_index_map keeps track of the indexes for each Soup.

 


 

  • TABLE_1 is a generically named table that contains my JSON data and Index values. The TABLE_1_0 field here is the “id” index we specified when we created the Soup. If I had created more indexes, like a “name” index, another column would be shown here.

 

 

The Soup field contains the full JSON response for that record so you can reuse whatever code you wrote to deal with the JSON record from the REST API once you’ve pulled it from the Soup.

 



So that’s SmartStore. It’s a great way to put together an app for Salesforce, Database.com, or Chatter that stores JSON data on the device for offline access.

facebooktwittergoogle_plusredditpinterestlinkedinmail Read More

Posted by on Nov 19, 2011 in Code, Mobile, The Cloud |

Using XMLHttpRequest2 in iOS 5 or Android OS 3 to download binary files using HTML5/Phonegap

One of the things added to Safari and UIWebView in iOS5 is support for XMLHttpRequest 2, which according to W3C adds new features “such as cross-origin requests, progress events, and the handling of byte streams for both sending and receiving”. As part of the last bit of that, it’s now possible to set the responseType to arraybuffer, which is “used to represent a generic, fixed-length binary data buffer”. More info here. This is useful if you want to download binary such as image or audio data from a remote location, and potentially manipulate it before presenting it to the user.

This has many possible applications for file transfer, but for instance, if you’re writing an HTML5 / PhoneGap app for iOS 5, and you want to download an attached file from the current version (v23.0) of the Chatter REST API, you need to send a GET request to:

https://test.salesforce.com/services/data/v23.0/chatter/files/[PUT THE FILE ID HERE]/content?versionNumber=1

But, you have to include a few headers for authentication…

setRequestHeader(“Authorization”, “OAuth ” + oauthToken);

setRequestHeader(‘X-User-Agent’, ‘salesforce-toolkit-rest-javascript/v23.0’);

…so it’s not like you can just dump the GET request into the src of an <img> tag. So, what you can do now in iOS 5 is send off an XMLHttpRequest with a responseType of “arraybuffer”, and use this data to write to a HTML5 Canvas object.

Here’s the XMLHttpRequest:

    var request = new XMLHttpRequest();     
    request.open(“GET”, url, true);
    request.responseType = “arraybuffer”;
    request.setRequestHeader(that.authzHeader, “OAuth ” + that.sessionId);
    request.setRequestHeader(‘X-User-Agent’, ‘salesforce-toolkit-rest-javascript/’ + that.apiVersion);
    request.onreadystatechange = function() {
        // continue if the process is completed
        if (request.readyState == 4) {
            // continue only if HTTP status is “OK”
            if (request.status == 200) {
                try {
                    // retrieve the response
                    callback(request.response);
                }
                catch(e) {
                    // display error message
                    alert(“Error reading the response: ” + e.toString());
                }
            }
        }            
    }
    request.send();

And here’s the body of the callback that handles Base64 encoding the arraybuffer and writing that data to a Canvas using the Data URI Scheme:

function(response){
    var imageCanvas = $('#'+value.id);
    var cxt = imageCanvas[0].getContext("2d");

    var myImage = new Image();

    myImage.src = "data:"+value.mimeType+";base64,"+base64ArrayBuffer(response);

    imageCanvas[0].width=myImage.width;
    imageCanvas[0].height=myImage.height;

    cxt.drawImage(myImage,0,0,myImage.width,myImage.height);
}

For the Base64 encoding, I used this handy function that I found over on PasteBin.
Note, I haven’t tested it, but this should (probably) work on Android OS 3.0 (Honeycomb) as well.
If you’re interested in doing all this with ForceTK, take a look at this Pull Request over on GitHub.
facebooktwittergoogle_plusredditpinterestlinkedinmail Read More

Posted by on Sep 13, 2011 in Code, Mobile, The Cloud, Videos |

Application Development with Android

This is a link to my Dreamforce 2011 session on Application Development with Android. Mobile application development sure is a hot topic these days, and the Android platform is gaining fast, especially with new tablet formats. Every mobile app needs a robust, secure, and capable database. So this coding session will walk you through creating an application on the Android platform by leveraging the power of Database.com. We’ll give you all the details you need to begin participating in the hottest segment of cloud development.

facebooktwittergoogle_plusredditpinterestlinkedinmail Read More