The Photofeed sample Java app demonstrates the use of several Google Cloud platform products in one application to provide a media sharing and management solution. It runs on App Engine and for datastore uses your choice of either the App Engine non SQL Datastore or Google Cloud SQL to store photo metadata and comments about the photos. The actual photo binaries (blobs) are stored in Google Cloud Storage (GCS) regardless of which datastore you choose. (The datastore choice is a build-time choice made via build properties prior to compiling the app; the default is the non SQL App Engine Datastore.)
In addition to showing how to use Google Cloud products to support the media sharing solution, the sample provides a variety of useful insights and techniques. For example, because the sample implements the same storage functionality using two different storage products (App Engine non SQL datastore and Google Cloud SQL), the code provides a real-world "side-by-side" comparison.
What This Sample Does
The user starts off by logging in with a valid Google account. After login, the user sees a shared photo stream containing photos and comments uploaded by the users of the app. The photos are displayed in the chronological order posted, and any comments for each photo are also shown in the chronological order posted.
A user accesses the app's main page (photofeed.jsp) via a browser. The app UI invites the user to login and view or upload photos, or comment on the photos currently uploaded:
The user posting a photo must supply a comment after choosing a file to upload to serve as the photo title. The uploader's comment appears below the photo, and any subsequent comments, including those from other users are displayed below the poster's original comment in the order posted:
The basic block-level architecture of the app looks something like this:
with the dotted line to Google Cloud SQL indicating its optionality. As shown, the photo binaries are stored in Google Cloud Storage. The photo images are uploaded from browser directly to GCS and are served to the browser directly from GCS. All other data (such as photo metadata and comments) is stored in your choice of App Engine Datastore or Google Cloud SQL.
Browser requests are routed to the Web Application hosted inside App Engine. The built-in auto-scaling of App Engine starts instances based on the amount of traffic, automatically load balancing the requests. Using the Blobstore API, App Engine generates URLs for uploading and serving files from Google Cloud Storage.
After the media files are uploaded to GCS, the original HTTP request is forwarded to a callback URL provided by the App Engine application. Via that callback, the web app inside App Engine uses the App Engine Datastore or Google Cloud SQL to store photo metadata, user information, and comments for the photos. The user can search for users, photo metadata, and comments in the datastore.
Media Data Flow
Photos are uploaded to and downloaded from GCS through the Google network. For download, the Google network honors HTTP caching headers and provides edge caching for media files. In the event of a cache miss, media data is requested from the Cloud Storage.
Architectural Components of the Sample
The main components of the architecture are described in the table:
|Web Applications inside App Engine||The photo sharing application is hosted inside Google App Engine(GAE). It handles all user requests from the browser, provides user interfaces for photo uploading, navigation, and comment posting. It also orchestrates the media data flow between the browser and the Google Cloud Storage.|
|App Engine Datastore||This non SQL datastore is used to store the metadata about each photo, including the description, user, timestamp, and a blob key to the media file in the Cloud Storage. It also hosts the application data model, such as the users and comments information.|
|Google Cloud SQL||This is an alternative to App Engine's non SQL datastore. You can switch between the two data store options by making a simple change in the build.properties configuration file.|
|Google Cloud Storage||The Google Cloud Storage (GCS) stores all the binary media files for the uploaded photos. The photos are uploaded and served directly between the user's browser and GCS using the App Engine Blobstore API.|
Caching and Load Balancing Supplied by Google's Network
All traffic from the Browser to the GCS and App Engine goes through the Google network. The Google network provides load balancing for requests to GCS and App Engine and supports standard HTTP caching headers. So media files are cached at the network edge, significantly improving the speed of serving static images.
Block Architecture of the Sample
The general architecture of the sample itself is shown below:
As shown in the diagram, the logical starting point of the app is the
JSP, photofeed.jsp, with PhotoServiceManager used to upload and serve
photo binaries to Google Cloud Storage. The top layer of the model code is
a generic datastore interface designed to work with both the non SQL App
Engine Datastore implementation and the implementation that uses Google
Cloud SQL. The choice is made at build time via
build.properties, and the currently used
implementation can be checked at runtime via
For More Detailed Descriptions
For more detailed descriptions, diagrams, code snippets and commentary see these pages: