In this session we'll talk about how the combination of cloud computing a flexible, lightweight dynamic language like Groovy and a few architectural and design principles can be used to create highly scalable and maintainable web applications. In this session we'll look into GAE (Google App Engine) and what Groovy offers to tap into the power of commodity cloud computing platforms. http://www.integrallis.com
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Integrallis groovy-cloud
1. Groovy on the GAE
Lightweight Scalable Web Applications on
The Google App Engine
Brian Sam-Bodden
Sunday, August 15, 2010
2. IN THIS PRESENTATION
• Cloud Computing
• Google App Engine
• Groovy Web Applications
• Groovy Web Applications on the Cloud
Sunday, August 15, 2010
3. Cloud Computing
Infrastructure, Platform and Software
Sunday, August 15, 2010
4. CLOUD COMPUTING
• Several new concepts:
• Infrastructure as a Service
• Platform as a Service
• Software as a Service
4
Sunday, August 15, 2010
5. CLOUD COMPUTING
• Offers many benefits...
• Horizontal Scalability On-Demand
• Not Only Horizontal but Elastic Scalability!
• Grow or Shrink based on needs
• Variable Cost Consumption
• Service-Oriented Architecture
• Always available 5
Sunday, August 15, 2010
6. CLOUD COMPUTING
• But it entails a re-thinking of current application design:
• Service-oriented design
• Dependencies as Services
• Relational Model MIGHT not cut it
• Data might not be “cloud” worthy :-)
6
Sunday, August 15, 2010
7. CLOUD COMPUTING
• But of course there are drawbacks...
• Data is only as secure as your provider
• RDBMS can still become a choke point
• Just like Security, Availability/Performance tied to the cloud
provider
• Shifting responsibilities entails shifting control
7
Sunday, August 15, 2010
9. GAE/J
• Philosophy behind GAE:
• We should focus on software and outsource the rest (to
Google :-)
• E.g. put the data center on your credit card
• High Availability and High Scalability on Demand
• Disk Space and CPU cycles as a metered commodity
9
Sunday, August 15, 2010
10. GAE/J
• Platform As a Service (PAAS)
• Development and Hosting Platform
• Provides Python and Java Support
• GAE for Java (GAE/J) allows Java Web Applications to run
on Google’s infrastructure
• Any Servlet-based application that can be package as a
WAR can theoretically be deployed on GAE
10
Sunday, August 15, 2010
11. GAE/J
• Typical application needs are provided by a variety of
(scalable) services:
• DataStore provided by BigTable
• Caching provided by Memcache via JCache (JSR-107)
• GWT, GoogleAccounts, MailAPI, XMPPApi, Cron,
TaskQueue
• Java Tools for testing, downloading logs, ant tasks, CLI tool
11
Sunday, August 15, 2010
12. GAE/J
• Deploying to the GAE comes with some strings attached:
• Cannot spawn threads
• Cannot write to the local filesystem
• Cannot open arbitrary network connections
• Cannot use JNI or other native code technologies
• There is RDBMS (No SQL, No Joins)
• Design for low latency (30 sec. request limit)
12
Sunday, August 15, 2010
13. BIGTABLE
•A no-sql solution described as a Distributed Storage System
for Structured Data
• A “BigTable” is defined as a sparse, distributed, persistent
multidimensional sorted map
• The map is indexed by row key, column key and a
timestamp; each value in the map is uninterpreted array of
bytes
• The row keys are arbitrary strings, every read/write
operation against a key is atomic and the table is ordered
lexicographically by row key
13
Sunday, August 15, 2010
14. BIGTABLE
• Cells (value of a column) contains multiple versions of the
same data, versioning is handed by a timestamp
• Configurable policy on how to garbage collect cell versions
• An Entity is a row, max number of entities returned is 1000
• No SQL, no joins instead you have GQL
• JPA/JDO adapters make BigTable sort of look like a
relational DB
14
Sunday, August 15, 2010
15. GAE/J
• To get started with GAE/J we need a GAE account. You can
open one at http://appengine.google.com/
15
Sunday, August 15, 2010
16. GAE/J
• The account is verified via a Text message:
16
Sunday, August 15, 2010
17. GAE/J
• The next step is to create/register an application:
17
Sunday, August 15, 2010
18. GAE/J
• Once the application has been registered we can view the
web based dashboard, use the appcfg CLI utility or add
Administrators to the application:
18
Sunday, August 15, 2010
19. GAE/J
• Once we deploy the application we’ll be able to view/edit
application configuration and see real time metrics:
19
Sunday, August 15, 2010
20. GAE/J
•A GAE/J provides an Eclipse plugin to ease development:
http://code.google.com/appengine/docs/java/tools/eclipse.html
20
Sunday, August 15, 2010
21. GAE/J
•A GAE/J provides an Eclipse plugin to ease development:
http://code.google.com/appengine/docs/java/tools/eclipse.html
20
Sunday, August 15, 2010
22. GAE/J
• We can locally launch the created application:
http://localhost:8888
21
Sunday, August 15, 2010
23. GAE/J
• Let’s turn the application into a simple Bookmarks
application using JPA to access BigTable datastore:
22
Sunday, August 15, 2010
26. GAE/J
• The EMF class is a singleton wrapper for the (slow to
create) EntityManagerFactory class
package org.integrallis.gae.bookmarks.dao;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public final class EMF {
private static final EntityManagerFactory emfInstance =
Persistence.createEntityManagerFactory("transactions-optional");
private EMF() {}
public static EntityManagerFactory get() {
return emfInstance;
}
}
24
Sunday, August 15, 2010
27. GAE/J
• The EMF class is a singleton wrapper for the (slow to
create) EntityManagerFactory class
package org.integrallis.gae.bookmarks.dao;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public final class EMF {
private static final EntityManagerFactory emfInstance =
Persistence.createEntityManagerFactory("transactions-optional");
private EMF() {}
public static EntityManagerFactory get() {
return emfInstance;
}
}
24
Sunday, August 15, 2010
28. GAE/J
• The Bookmark POJO is a simple JPA Entity:
@Entity
public class Bookmark {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
private String url;
private Date createdAt;
private String ownerId;
...
}
25
Sunday, August 15, 2010
29. GAE/J
• The Bookmark POJO is a simple JPA Entity:
@Entity
public class Bookmark {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
private String url;
private Date createdAt;
private String ownerId;
...
}
25
Sunday, August 15, 2010
30. GAE/J
• The Bookmarks.jsp shows a list of all bookmarks for a
User and provides a form for adding a new Bookmark:
...
<html>
<head>
<title>Bookmarks</title>
</head>
<body>
<%
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
String url = userService.createLoginURL(request.getRequestURI());
String urlLinktext = "Login";
List<Bookmark> bookmarks = new ArrayList<Bookmark>();
if (user != null){
url = userService.createLogoutURL(request.getRequestURI());
urlLinktext = "Logout";
EntityManager em = EMF.get().createEntityManager();
Query query = em.createQuery("SELECT FROM Bookmark b WHERE b.ownerId = :ownerId");
query.setParameter("ownerId", user.getUserId());
bookmarks = query.getResultList();
}
%>
<h1>GAE Bookmarks</h1>
...
26
Sunday, August 15, 2010
31. GAE/J
• The Bookmarks.jsp shows a list of all bookmarks for a
User and provides a form for adding a new Bookmark:
...
<html>
<head>
<title>Bookmarks</title>
</head>
<body>
<%
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
String url = userService.createLoginURL(request.getRequestURI());
String urlLinktext = "Login";
List<Bookmark> bookmarks = new ArrayList<Bookmark>();
if (user != null){
url = userService.createLogoutURL(request.getRequestURI());
urlLinktext = "Logout";
EntityManager em = EMF.get().createEntityManager();
Query query = em.createQuery("SELECT FROM Bookmark b WHERE b.ownerId = :ownerId");
query.setParameter("ownerId", user.getUserId());
bookmarks = query.getResultList();
}
%>
<h1>GAE Bookmarks</h1>
...
26
Sunday, August 15, 2010
32. GAE/J
• The AddBookmark Servlet uses JPA to persist a new
Bookmark
public class AddBookmark extends HttpServlet {
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String url = req.getParameter("url");
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
Bookmark bookmark = new Bookmark(url, Calendar.getInstance().getTime(), user.getUserId());
EntityManager em = EMF.get().createEntityManager();
try {
em.persist(bookmark);
} finally {
em.close();
}
resp.sendRedirect("/Bookmarks.jsp");
}
}
27
Sunday, August 15, 2010
33. GAE/J
• The AddBookmark Servlet uses JPA to persist a new
Bookmark
public class AddBookmark extends HttpServlet {
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String url = req.getParameter("url");
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
Bookmark bookmark = new Bookmark(url, Calendar.getInstance().getTime(), user.getUserId());
EntityManager em = EMF.get().createEntityManager();
try {
em.persist(bookmark);
} finally {
em.close();
}
resp.sendRedirect("/Bookmarks.jsp");
}
}
27
Sunday, August 15, 2010
34. GAE/J
• The traditional web.xml glues the application together:
<web-app>
<servlet>
<servlet-name>AddBookmark</servlet-name>
<servlet-class>org.integrallis.gae.bookmarks.AddBookmark</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AddBookmark</servlet-name>
<url-pattern>/new</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>Bookmarks.jsp</welcome-file>
</welcome-file-list>
</web-app>
28
Sunday, August 15, 2010
35. GAE/J
• The traditional web.xml glues the application together:
<web-app>
<servlet>
<servlet-name>AddBookmark</servlet-name>
<servlet-class>org.integrallis.gae.bookmarks.AddBookmark</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AddBookmark</servlet-name>
<url-pattern>/new</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>Bookmarks.jsp</welcome-file>
</welcome-file-list>
</web-app>
28
Sunday, August 15, 2010
36. GAE/J
• The appengine-web.xml deployment descriptor ties this
application to the previously registered GAE application:
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>nfjs-austin</application>
<version>1</version>
<!-- Configure java.util.logging -->
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
</appengine-web-app>
29
Sunday, August 15, 2010
37. GAE/J
• The appengine-web.xml deployment descriptor ties this
application to the previously registered GAE application:
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>nfjs-austin</application>
<version>1</version>
<!-- Configure java.util.logging -->
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
</appengine-web-app>
29
Sunday, August 15, 2010
38. GAE/J
• You can run the application locally:
30
Sunday, August 15, 2010
39. GAE/J
• You can inspect the application deployment properties via
the project properties “Google” tab:
31
Sunday, August 15, 2010
40. GAE/J
• You can inspect the application deployment properties via
the project properties “Google” tab:
32
Sunday, August 15, 2010
41. GAE/J
• Dashboard View of nfjs-austin Version 1:
33
Sunday, August 15, 2010
42. GAE/J
• The Bookmark application running on the cloud:
http://nfjs-austin.appspot.com
34
Sunday, August 15, 2010
44. GROOVY
• Groovy...
• is a modern object-oriented dynamic language
• was designed specifically for the Java VM
• reflects the evolution of the Java community
• syntax feels like Java without the clutter
• embraces and extends Java
36
Sunday, August 15, 2010
45. GROOVY
• Groovy...
• produces Java byte code
• add features found in most modern dynamic languages:
• Flexible Type System, Closures, Meta-programming,
Simple Collections, Operator Overloading and many
more
37
Sunday, August 15, 2010
46. GROOVLETS
• Groovlets are Groovy scripts which are rendered by a
Groovy Servlet dispatcher
• For example the simple Groovlet below uses the html
variable (an instance of MarkupBuilder) to programmatically
construct an HTML document:
html.html {
head {
title "Hello"
}
body {
p "Hello Groovy World!"
}
}
38
Sunday, August 15, 2010
47. GROOVLETS
• Groovlets have implicit variables to access the session, the
output stream and the request and response objects
if (!session) {
session = request.getSession(true)
}
if (!session.counter) {
session.counter = 1
}
html.html {
head {
title("Groovy Servlet")
}
body {
p("Hello, ${request.remoteHost}: ${session.counter}! ${new Date()}")
}
}
session.counter = session.counter + 1
39
Sunday, August 15, 2010
48. RATPACK
•A new entry into the Groovy Web Development world is
Ratpack a Groovy clone of Ruby’s Sinatra Web Framework
• Like Sinatra, Ratpack is a DSL for quickly creating web
applications in Groovy with minimal effort
import ratpack.Ratpack
import ratpack.RatpackServlet
def app = Ratpack.app {
get("/") {
"Hello, World!"
}
}
RatpackServlet.serve(app)
40
Sunday, August 15, 2010
49. RATPACK
• Ratpack applications can be launch directly from the
command line:
41
Sunday, August 15, 2010
50. Groovy On GAE
Project Gaelyk
Sunday, August 15, 2010
51. Groovy On GAE
Project Gaelyk
Sunday, August 15, 2010
52. GAELYK
• Gaelyk is a lightweight Groovy toolkit build on top of GAE/J
• allows you to use of Groovlets instead Servlets
• allow you to use Groovy Templates
• and simplifies and enhances the GAE/J SDK
• created by Guillaume Laforge, Groovy Project Manager
and co-creator of the Grails framework
http://gaelyk.appspot.com
43
Sunday, August 15, 2010
53. GAELYK
• Gaelyk provides a project template:
Groovlets go here!
A Groovy AntBuilder build script
Project specific Java/Groovy files (other
than templates and Groovlets)
44
Sunday, August 15, 2010
54. GAELYK
• We can use the Gaelyk template to enhance a GAE/J Eclipse
Web Application:
45
Sunday, August 15, 2010
55. GAELYK
• We can run the Gaelyk application locally to test that the
basic template works:
46
Sunday, August 15, 2010