Part 2: Actual Cloud
In Part 1 of this series, we took a
quick high-level look at the various parts of Google Cloud Platform, then dove
into getting a "Hello World" app up and running in Google App Engine. Google App
Engine being a Java Servlet-based environment, it was pretty much an exercise
in writing a simple Servlet and making sure the Servlet deployment descriptor
has the necessary elements for Google App Engine. But we left out an important
part of that story.
We, uh ... we never actually deployed it to the cloud.
Cloud-ifying
Assuming the local machine has the code running from last
time (see Google Cloud Platform: Getting Started with Google App Engine (Part 1) if you didn’t read the first part), the code is
running in a local copy of Google App Engine environment. To get it into the
cloud, we have to do a couple of things first; in particular, we need to get a
Google Cloud Platform account up and running, then configure an environment in
which this application will be deployed.
It starts by signing up with your Google account (what
developer doesn’t have a Gmail account by now?), and then heading over to http://cloud.google.com/console and
creating a project. The dialog will ask for two bits: a project name, and a
project identifier, which Google will generate for you. The identifier is the
important part as far as Google is concerned—this is the unique value that
identifies the project among all of the other projects running on the cloud,
hence the reason Google suggests a value. It will end up being the default
domain (<identifier>.appspot.com) the application is accessed through, if
no DNS CNAME records are set up to alias it (which is a little beyond the scope
of this article).
Once that’s done, the project is created, and waiting for
code.
Deploy
The Ant script from Part 1 can push the application into the
cloud, but the local tooling needs to know a few things before it can
successfully do so. Specifically, it needs to know the application identifier,
and it needs to know that the fingers in front of the keyboard belong to the
party who actually owns the space in the cloud. To do the former, we need to
edit the <application>
element in the appengine-web.xml descriptor to
read the application identifier; thus, since my sample application was given
the identifier "summer-scion-375
", the <application>
element should read:
="1.0" ="utf-8"
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>summer-scion-375</application>
<version>1</version>
<threadsafe>true</threadsafe>
</appengine-web-app>
The <version>
element is also important, by the way,
but we’ll get to that in a moment.
Once that’s done, run a shell script/batch file that comes
from Google SDK called "appcfg" (appcfg.sh on MacOS/*nixes). This little tool
will scan the appengine-web.xml file for settings (application and version),
then ask for your Google credentials, and then promptly pull all the code into
the cloud. The same script gets called from "ant update", so use whichever
makes more sense. (I prefer to do everything through Ant, since then I can
automate certain tasks before doing the update, such as a commit to source
control or processing configuration files to set for development-vs-production
settings, and so on; choose as you wish.) The first time, however, it must be
called from the command-line, so fire up "appcfg update war", where the first
parameter is to upload the app, and the second is the location of the WEB-INF
directory in which appengine-web.xml can be found. It will prompt for the
Google account email and password, then upload the application.
If something should go wrong with the deploy, by the way,
such as a network timeout or something similar during its processing, do an
"appcfg rollback war" to clean up local files and try again. For those who are
curious, appcfg has a slew of command-line parameters to customize the
experience (including the "--passin" command, which requires the password
to be typed in every time), and are discovered in the usual manner: "appcfg
help". (Or you could read the page on it at http://developers.google.com/appengine/docs/java/tools/uploadinganapp,
but where’s the fun in that?)
Once the update is done, the app is good to go: head over to
the browser, fire up "http://summer-scion-375.appspot.com/hello", and bask in
the warm goodness of yet another "Hello, World" application running on the
Internet. (Bear in mind there’s actually two hello’s here—one at the root, the
index.html file we created last time, as well as the servlet behind the
"/hello" URL pattern.)
Dashboarding
Before we move off of this, take a second and look again at
Google Cloud Console, where you created the project. Click the link for your
created project so you’re in the Console view for the project alone, and on the
left side, about halfway down the sidebar is the "Google App Engine" link,
which opens a new browser tab to the App Engine dashboard. These are two
separate consoles—the Console is the "big picture" view of the project, with
links to the different parts of Google Cloud Platform that your application
touches, including Google App Engine, Google Cloud Storage, Google Cloud SQL, and so
on. By itself, it’s not a particularly data-filled dashboard, but it’s the hub
for all other dashboards.
Google App Engine dashboard, on the other hand, is a
metric-lover’s delight. Immediately upon being loaded into the browser page, Google
App Engine dashboard presents the developer/administrator with a ton of data
about the running application, including a lovely graph in the center of the
page (with a variety of settings in the dropdown under "Charts" to change what
data is displayed) and—perhaps the most important information an application
owner needs—a grid of resource consumption statistics under the section labeled
"Billing Status". See Figure 1 for the view of my example app. More
importantly, hiding behind the "Settings" link next to "Billing Status" is the
all-important "Enable Billing" and "Enable Billing Administrators" buttons to
configure how, when and to where Google will charge money in exchange for more
cloud resources.
However, one other thing needs noting: right above the
"Charts" section in the Dashboard is a dropdown labeled "Version", and
currently it’s set to "1", which is also marked as "(Default)". Google App
Engine recognizes that developers often want to have different versions of the
code (at the very least, we have the current version "n", the previous version
"n-1" that represents a quick fallback-in-case-we-screwed-something-up-version,
and the next version "n+1" that represents the
we-want-to-try-this-out-and-see-if-we-screwed-something-up version). This value
is controlled by the <version>
tag in appengine-web.xml, so if we make a
change to the Java code (perhaps we look for the "name" query parameter, and
use that to customize the greeting a little) and mark <version>
as 2, and
"ant update", versions 1 and 2 will be available in said dropdown.
Having said that, once version 2 is uploaded successfully,
something seems wrong: pointing the browser to the http://summer-scion-375.appspot.com
URL again reveals that nothing’s changed. This is because Google App Engine
won’t automatically route traffic to version 2 until told to do so, which is
done by clicking the "Versions" link in the left-hand sidebar, and selecting
"2" in the table displayed there, then making it the default application by
pushing "Make Default". This is by design; version 2 won’t be active until it
is the default.
"Default" implies that there’s other ways to see that
version of the application. Google App Engine will keep several versions of the
code on the server simultaneously, and point traffic to the version marked
"default". You can, however, craft a URL to visit any given version of an
application by browsing to
"http://<version>.<identifier>.appspot.com". Since version 2 is the
default for summer-scion-375, that’s what is displayed without the version
prefix, but we can still visit version 1 (or version 3, when we later enhance
the application again to include something truly radical, like the current date
and time) by going to "http://1.summer-scion-375.appspot.com".
A little something ... more
Although the Web originally was born of hyperlinked
documents, complete with <blink>
tags, animated GIFs, imagemaps and home
pages that played your favorite music clip (see http://www2.warnerbros.com/spacejam/movie/jam.htm
for a quick peek into that lovely past), over the last few years the Web has
slowly turned into a collection of data, rather than documents. Going by the
"Web 2.0" moniker, it’s becoming more common for cloud-deployed "applications"
to actually be nothing more than data endpoints accessed over HTTP and serving
up XML or JSON to a variety of endpoints: single-page HTML/JavaScript/CSS,
mobile, or (sometimes) desktop applications. So while we could certainly explore
one or more of the various Java toolkits/frameworks that will generate HTML on
the server and hand that back, 2003 called, and it wants its code back. This is
2013, and we want to build a "Web 2.0" application.
One approach to doing so would be to take the existing
servlet application, create a series of endpoints ("/greeting") that accept an
incoming JSON packet (something like "{name:’Fred’}"), parse it, process it,
and hand back an outgoing JSON packet ("{message:’Hello, Fred!’}
"), all by hand
in Java, but that’s a lot of work. In particular, parsing and preparing the
JSON endpoints are going to bog a lot of this down, since we would be
serializing and deserializing to a text format, complete with lack of
type-checking and verification. (Remember how much fun this was to do with XML
back in the WS-* web service days?)
Fortunately, Google App Engine provides a "backend"
specifically for building these kinds of endpoints, and we’ll look at how to
use it to create a greeting service that provides this
kind of data-driven functionality. Before we can do that, though, we have to
figure out who the user is, in order to greet them properly, which will be the
subject of the next article. In the meantime, however, should you ever feel
alone, there’s a web application waiting to say hello to you, so keep a browser
tab open, and happy coding!
Figure 1: summer-scion-375 Dashboard