Roshan has posted 7 posts at DZone. View Full User Profile

Implementing a Tag-Cloud App on Google App Engine with JDO + Security + Groovy Server Pages

09.02.2010
| 8177 views |
  • submit to reddit

This article introduces the steps involved in making a web application for Google App Engine platform that uses Google’s persistence and security infrastructure. The application for demonstration is a basic tag-cloud implementation - http://mytagclouds.appspot.com/.

Objective

The purpose of the article is not to go in depth of all aspects of the application and evaluate all the options available at every step - JDO or JPA (for persistence on GAE), authentication against Google accounts or a OpenId - with application access through sub-domains or not, Groovy Server Pages or Grails or Gayelk, jQuery or GWT, POJOs or POGOs, etc. 

The purpose is to take one cross-section of the alternatives available (JDO, authentication against Google accounts, Groovy Server Pages, jQuery, POJOs) and figure out what all is needed to put in place a potentially useful application that is backed by Google’s security, persistence infrastructure and various other back-end systems!

For additional information on various aspects, I will try to point to resources with relevant information.

Demo Application

The demo application(http://mytagclouds.appspot.com/) is a simple one - it lets you maintain the items of your interest by categories and tag them with some keywords. The application persists your items and presents a categorized tag-cloud view of your items.

The application is built using mainly the following technologies:

  •  The UI is build using Groovy Server Pages
  • Application level authentication against existing Google accounts.
  • Application level persistence using JDO framework.
  • The tag-cloud implementation and Ajax features are done using jQuery library.

Here is the overall functionality of the application:

  • Add the item categories of your interest
  • Maintain items under these categories and label them with various tags
  • Tag-cloud view of items and navigation through this tag-cloud view.


 The Development Environment

 The Google App Engine SDK comes with a plugin for Eclipse that can be downloaded from here

This plugin has a web server that emulates the App Engine services on your local computer and has the necessary libraries packaged with it. For example, if you have decided to secure your application, the web server will throw a standard login-page and if you have decided to use JDO for persistence on App Engine, there is nothing else that needs to be installed for that - the plugin comes with a persistence store built-in - simply fire away your JDO DB queries!

Apart from emulating the App Engine services, the plugin gives two more things:

  •  GWT (Google Web Toolkit) support
  • Deployment from your local eclipse environment to google app engine servers is 1-click thing.

 

Application Security

When you first create an application entry in your app engine account, you need to choose how you would like to authentication the users of your application. The choices include authentication against existing Google Accounts, OpenID, etc. The relevant details can be found here.

For the purpose of the demo application, I chose to do the authentication against the Google Accounts API. The only configuration needed for that is the definition of security constraint (<security-constraint>) in your web.xml. (Note that you cannot define any custom security roles (<security-role>) or alternate authentication mechanisms (<login-config>)).

For the demo application, here is the relevant configuration:

<security-constraint>
<web-resource-collection>
<web-resource-name>All Access</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>

That’s it. Once the application is deployed with this security configuration, when it is accessed, the app engine presents the user with the standard login page as below.

 

As the login page from Google highlights above, the app engine is responsible for making sure that the application only gets the authenticated user's mail-id (using request.getUserPrincipal().getName()) to personalize the application's state and making sure that the application has no access whatsoever to the user's login credentials.

Persistence

The app engine supports 2 ways of persisting the data currently - Java Data Objects (JDO) and Java Persistence API (JPA). The data is stored in a schemaless object store and not in a relational database. Details regarding persistence on app engine can be found here.

The demo application uses JDO to persist the following information: categories, items and tags. While it is quite simple to handle persistence of individual entities, things get a little tricky when you have 1-to-many kind of relationships between entities, so below are some details relevant to JDO persistence used:

Persisting a single entity

Marking the entities with JDO specific annotations

@PersistenceCapable
public class Item {

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;

@Persistent
private String userId;
...
...
...
}

Querying the data using JDO query language JDOQL:

PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory("transactions-optional");

PersistenceManager pm = pmf.getPersistenceManager();

String query = "select from " + Item.class.getName() + " where userId == '" +
userId + "' && category == '" + categoryName + "'";

items = (List<Item>) pm.newQuery(query).execute();

Persisting entities with 1-to-many relationships

The code below highlights the JDO configuration needed to handle 1-to-many relationship between an item and tags:

@PersistenceCapable
public class Item {

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;

@Persistent
private String userId;

...
...
/* this is the property that is used as foreign key */
@Persistent(mappedBy = "item")
private List<Tag> tags; /* collection to hold an item’s many tags */
...
...
}

@PersistenceCapable
public class Tag {

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key id;

...
...
private Item item; /* should be the same key as used in mappedBy above */
...
...
}

Application level configuration

In addition to the web application’s web.xml, app-engine specific configuration needs to be done in a configuration file named appengine-web.xml. Some of the things that I needed to configure here were:

  • <application> - this needs to be your application’s registered application id on the app engine. The application id "mytagclouds" will be accessible as http://mytagclouds.appspot.com
  • <version> - you can have multiple versions of your application running at same time, if you want.  For instance, a specific version can be accessed as http://3.latest.mytagclouds.appspot.com/ but http://mytagclouds.appspot.com will point to the most recently deployed version.
  •  <static-files> - App engine physically divides an application’s static and dynamic content to achieve better performance. The static content is deployed on dedicated web servers and is more easily distributed/replicated.
  • <includes>/<excludes> - these elements can be used to specifically tell which content you want app engine to treat as static content. For example, for this demo application, if Groovy Server Pages (*.gsp) are not excluded from <static-files>, the app engine will serve the file’s code when accessed and instead of letting the groovy engine process these *.gsp files and serve the generated content instead.
  • <sessions-enabled> - if you want to maintain data in session, you need to explicitly enable it first to avoid runtime exceptions from app engine servers.

More information about appengine-web.xml can be found here.

Deployment to Google App Engine

Once your application is developed and locally tested with the help of app engine SDK and its emulated app engine services, it’s a breeze to deploy the application on app engine using the eclipse-plugin.

Or, if you prefer doing it from command line (say, after performing some app specific build steps - for ex, compilation of your groovy scripts), the deployment from command line is as simple as the following command from the application directory:

appcfg update war

You may be prompted for your google account credentials to upload your application under your google app engine environment.

And that’s it. Your application is now ready to serve from app engine.

Monitoring and troubleshooting your application

App engine provides a comprehensive dashboard that lets you monitor how your application is doing on the cloud. Consolidated logs are available to help you troubleshoot any issues that may surface.

 

That's all I had to share in this article. Thanks for reading. Please share your feedback/comments - there is much to learn in this space and it's just the beginning.

If anyone is interested in the code for this demo example, send me a line at roshandawrani@codehaus.org and I will be happy to share it.

Published at DZone with permission of its author, Roshan Dawrani.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)