82
Gaelyk Skyrocketing Groovy into the cloud! Guillaume Laforge Groovy Project Manager SpringSource / VMware jeudi 19 mai 2011

Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Embed Size (px)

Citation preview

Page 1: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

GaelykSkyrocketing Groovy

into the cloud!

Guillaume LaforgeGroovy Project ManagerSpringSource / VMware

jeudi 19 mai 2011

Page 2: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

GaelykSkyrocketing Groovy

into the cloud!

Guillaume LaforgeGroovy Project ManagerSpringSource / VMware

jeudi 19 mai 2011

Page 3: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Guillaume Laforge

• Groovy Project Manager• JSR-241 Spec Lead• Head of Groovy Development

at SpringSource / VMWare• Initiator of the Grails framework• Creator of the Gaelyk toolkit• Co-author of Groovy in Action

• Speaker: JavaOne, QCon, JavaZone, Sun TechDays, Devoxx, The Spring Experience, SpringOne, JAX, Dynamic Language World, IJTC, and more...

2jeudi 19 mai 2011

Page 4: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Guillaume Laforge

• Groovy Project Manager• JSR-241 Spec Lead• Head of Groovy Development

at SpringSource / VMWare• Initiator of the Grails framework• Creator of the Gaelyk toolkit• Co-author of Groovy in Action

• Speaker: JavaOne, QCon, JavaZone, Sun TechDays, Devoxx, The Spring Experience, SpringOne, JAX, Dynamic Language World, IJTC, and more...

2jeudi 19 mai 2011

Page 5: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

IaaS, PaaS, SaaS

• Software as a Service–Gmail, SalesForce.com

• Platform as a Service–Google App Engine

• Infrastructure as a Service–Amazon EC2

SaaS

PaaS

IaaS3

jeudi 19 mai 2011

Page 6: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

IaaS, PaaS, SaaS

• Software as a Service–Gmail, SalesForce.com

• Platform as a Service–Google App Engine

• Infrastructure as a Service–Amazon EC2

SaaS

PaaS

IaaS3

jeudi 19 mai 2011

Page 7: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

IaaS, PaaS, SaaS

• Software as a Service–Gmail, SalesForce.com

• Platform as a Service–Google App Engine

• Infrastructure as a Service–Amazon EC2

SaaS

PaaS

IaaS3

jeudi 19 mai 2011

Page 8: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Google App Engine

• Google’s PaaS solution–Run your app on Google’s infrastructure

• Initially just Python supported

• Java support added too–Sandboxed JVM–Jetty servlet container

• Several JVM-compatible language supported

4jeudi 19 mai 2011

Page 9: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Key aspects

• You can use most of your usual web frameworks for developping apps on App Engine Java–A WAR file, basically! (an exploded war actually)

– Uploading to the cloud by sending deltas of changes

• No OS image, or software to install– Unlike with Amazon EC2

• All the scaling aspects are handled for you– Database / session replication, load balancing...

• There are quotas, but you need a high traffic application to start being charged–Free to get started

5jeudi 19 mai 2011

Page 10: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Some of the available services

•Memcache– JCache implementation

– Save on CPU and datastore

•URL Fetch– Access remote resources– HttpUrlConnection

•Mail– Support both incoming and

outgoing emails

•Images– Resize, crop, rotate...

•XMPP– Send / receive Jabber

messages (GTalk)

•User– Use Google’s user/

authentication system

– OAuth support

•Cron & Task queues– Schedule tasks at regular

intervals– Queue units of work

•Blobstore– For storing large content

6jeudi 19 mai 2011

Page 11: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Limitations

•30 seconds request duration limit

–Task queues raised to 10 minutes

–Notion of Backends servers since 1.5.0

• Forbidden to –write on the file system–create threads–use raw sockets–issue system calls–use IO / Swing / etc. directly

•There’s a whitelist of classes allowed

• Number of files and their size are limited

7jeudi 19 mai 2011

Page 12: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Quotas & Billing

8jeudi 19 mai 2011

Page 13: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmarkjeudi 19 mai 2011

Page 14: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmark

Free tier

jeudi 19 mai 2011

Page 15: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmarkjeudi 19 mai 2011

Page 16: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmark

No infinitescaling!

jeudi 19 mai 2011

Page 17: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmarkjeudi 19 mai 2011

Page 18: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmark

No more usage based

jeudi 19 mai 2011

Page 19: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmarkjeudi 19 mai 2011

Page 20: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmark

Paid tier w/free quota

jeudi 19 mai 2011

Page 21: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmarkjeudi 19 mai 2011

Page 22: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmark Support!jeudi 19 mai 2011

Page 23: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmarkjeudi 19 mai 2011

Page 24: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmarkjeudi 19 mai 2011

Page 25: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmark

Reduced quotas

jeudi 19 mai 2011

Page 26: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmarkjeudi 19 mai 2011

Page 27: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmark

The Datastore

jeudi 19 mai 2011

Page 28: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

The datastore...

• Distributed key / value store– Based on Google’s «BigTable»

– Schema-less approach

• Supporting– Transactions and partitioning

– Hierarchies through entity groups

• Data access APIs– JPA and JDO

• but adds a big request load time factor

– Direct low-level APIs

12jeudi 19 mai 2011

Page 29: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

...and its «limitations»

• You’re not using SQL–No joins–No database constraints–No aggregation functions (count, avg...)

• In a query, you can only filter on one column for inequality

• Transactions only available in entity groups• You can only update an entity once in a transaction• No full text search capability

13jeudi 19 mai 2011

Page 30: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmark

Nice dashboard

jeudi 19 mai 2011

Page 31: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, DenmarkF

http://gaelyk.appspot.com

jeudi 19 mai 2011

Page 32: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, DenmarkF

http://gaelyk.appspot.com

jeudi 19 mai 2011

Page 33: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

• Gaelyk is a lightweight Groovy toolkit on top of the Google App Engine Java SDK

• Gaelyk builds on Groovy’s servlet support–Groovlets: Groovy scripts instead of raw servlets!–Groovy templates: JSP-like template engine–Both allow for a clean separation of views and logic

• Gaelyk provides several enhancements around the GAE Java SDK to make life easier, thanks to Groovy’s dynamic nature

16jeudi 19 mai 2011

Page 34: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Gaelyk 0.7 released

• Right on time for GR8Conf

• What’s new?–Upgraded to Groovy 1.8 and GAE SDK 1.5–XMPP presence and subscription support–Support for the files service and initial support for the

backends service–New variables for files service, backends service, and

lifecycle manager–Datastore metadata querying methods

17jeudi 19 mai 2011

Page 35: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Why Groovy?

• Groovy is a dynamic language for the JVM–very flexible, malleable, expressive and concise syntax–easy to learn for Java developers

•deriving from the Java 5 grammar

–provides powerful APIs to simplify the life of developers•possibility to dynamically enrich existing APIs

–support for Groovlets and its own template engine

18jeudi 19 mai 2011

Page 36: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmark

First steps...

• Go to http://gaelyk.appspot.com

• Download the template project

• Put your first Groovlet in /WEB-INF/groovy

• And your templates in /WEB-INF/pages

• And you’re ready to go!

• Launch dev_appserver.sh

• Go to http://localhost:8080/

jeudi 19 mai 2011

Page 37: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

The web.xml

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">

<listener> <listener-class>groovyx.gaelyk.GaelykServletContextListener</servl

et-class>

</listener> <servlet> <servlet-name>GroovletServlet</servlet-name>

<servlet-class>groovyx.gaelyk.GaelykServlet</servlet-class>

</servlet> <servlet> <servlet-name>TemplateServlet</servlet-name>

<servlet-class>groovyx.gaelyk.GaelykTemplateServlet</servlet-class>

</servlet>

<servlet-mapping> <servlet-name>GroovletServlet</servlet-name>

<url-pattern>*.groovy</url-pattern>

</servlet-mapping> <servlet-mapping> <servlet-name>TemplateServlet</servlet-name>

<url-pattern>*.gtpl</url-pattern>

</servlet-mapping></web-app>

20jeudi 19 mai 2011

Page 38: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

MVC: Groovlets and templates

Groovlets(controllers)

Templates(views)

Entities(domain)

21jeudi 19 mai 2011

Page 39: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

A groovlet

• Instead of writing full-blown servlets, just write Groovy scripts (aka Groovlets)

def numbers = [1, 2, 3, 4]def now = new Date()

html.html { body { numbers.each { number -> p number } p now }}

22jeudi 19 mai 2011

Page 40: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

A groovlet

• Instead of writing full-blown servlets, just write Groovy scripts (aka Groovlets)

def numbers = [1, 2, 3, 4]def now = new Date()

html.html { body { numbers.each { number -> p number } p now }}

22

Auto-reloading

jeudi 19 mai 2011

Page 41: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

A template

<html> <body> <p><% def message = "Hello World!" print message %> </p> <p><%= message %></p> <p>${message}</p> <ul> <% 3.times { %> <li>${message}</li> <% } %> </ul> </body></html>

23jeudi 19 mai 2011

Page 42: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

A template

<html> <body> <p><% def message = "Hello World!" print message %> </p> <p><%= message %></p> <p>${message}</p> <ul> <% 3.times { %> <li>${message}</li> <% } %> </ul> </body></html>

23

Auto-reloading

jeudi 19 mai 2011

Page 43: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Shortcuts

•Google services–datastore, blobstore–backends, lifecycle–memcache–capabilities–images–urlFetch–mail–userService / user–defaultQueue / queues–xmpp–namespace

•Variables available–request / response–context / application–sessions–params / headers–out / sout / html–localMode / app.*

•Methods available–include / forward /

redirect–println / print

24jeudi 19 mai 2011

Page 44: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmark

Groovy sugar!

jeudi 19 mai 2011

Page 46: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

...compared to Java

Properties props = new Properties();

Session session = Session.getDefaultInstance(props, null);

try { Message msg = new MimeMessage(session);

    msg.setFrom(new InternetAddress("[email protected]"));

    msg.addRecipient(Message.RecipientType.TO,

                     new InternetAddress("[email protected]"));

    msg.setSubject("Hello World");

    msg.setText("<bold>Hello</bold>");

    Transport.send(msg);} catch (AddressException e) {}

} catch (MessagingException e) {}

27jeudi 19 mai 2011

Page 47: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Unfair comparision?

28jeudi 19 mai 2011

Page 48: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Unfair comparision?

28jeudi 19 mai 2011

Page 49: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Unfair comparision?

28jeudi 19 mai 2011

Page 50: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Accessing the datastore

• Direct interaction with the low-level datastore API

Entity entity = new Entity("person") // subscript notation, like when accessing a mapentity['name'] = "Guillaume Laforge" // normal property access notationentity.age = 32

entity.save() // asyncSave()entity.delete() // asyncDelete()

datastore.withTransaction { // do stuff with your entities // within the transaction}

// use the asynchronous datastore servicedatastore.async.put(entity)

29jeudi 19 mai 2011

Page 51: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Querying to be improved...

import com.google.appengine.api.datastore.*import static com.google.appengine.api.datastore.FetchOptions.Builder.* // query the scripts stored in the datastoredef query = new Query("savedscript") // sort results by descending order of the creation datequery.addSort("dateCreated", Query.SortDirection.DESCENDING) // filters the entities so as to return only scripts by a certain authorquery.addFilter("author", Query.FilterOperator.EQUAL, params.author)

 PreparedQuery preparedQuery = datastore.prepare(query) // return only the first 10 resultsdef entities = preparedQuery.asList( withLimit(10) )

30jeudi 19 mai 2011

Page 52: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

...into something groovier?

def entities = datastore.query { select all from savedscript sort desc by dateCreated where author == params.author limit 10} as List

31jeudi 19 mai 2011

Page 53: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

...into something groovier?

def entities = datastore.query { select all from savedscript sort desc by dateCreated where author == params.author limit 10} as List

Still not im

plemented!

31jeudi 19 mai 2011

Page 54: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

URL Routing system

• You can have friendly URL mappings with the URL routing system

–RouteFilter should be configured in web.xml

all "/aboutus", redirect: "/blog/2008/10/20/about-us"

all "/blog/@year/@month/@day/@title", forward: "/blog.groovy?year=@year&month=@month@day=@day@title=@title"

get "/blog/@year/@month/@day", forward: "/blog.groovy?year=@year&month=@month@day=@day"

get "/book/isbn/@isbn", forward: "/book.groovy?isbn=@isbn", validate: { isbn ==~ /\d{9}(\d|X)/ }

32jeudi 19 mai 2011

Page 55: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

URL Routing system

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">

... <filter> <filter-name>RoutesFilter</filter-name>

<filter-class>groovyx.gaelyk.routes.RoutesFilter</filter-class>

</filter>

<filter-mapping> <servlet-name>RoutesFilter</servlet-name>

<url-pattern>/*</url-pattern> </filter-mapping> ...</web-app>

33jeudi 19 mai 2011

Page 56: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

URL Routing system

• You can also define caching times

–Nice for GAE’s infamous «loading requests»•less critical since GAE SDK 1.4

–warmup requests–and with paid tier, you can have instances pre-allocated

get "/aboutus", cache: 24.hours, forward: "/aboutus.gtpl"

get "/breaking-news", cache: 1.minute, forward: "/news.groovy?last=10"

34jeudi 19 mai 2011

Page 57: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

URL Routing system

• Special routes for specifying–incoming emails–jabber chat messages–jabber presence and subscription messages

35

email to: "/incomingMail.groovy"

jabber to: "/incomingXmpp.groovy"// synonym: jabber chat, to: "..."

jabber presence, to: "/subs.groovy"jabber subscrpition, to: "/subs.groovy"

jeudi 19 mai 2011

Page 58: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

URL Routing system

• Namespace awareness: nice for multitenancy• Capability awareness: for graceful degradation

36

// @cust customer variable could be « acme »post "/@cust/update", forward: "/update.groovy", namespace: { "ns-$cust" }

// different destinations depending on the GAE services status

get "/speakers", forward { to "/speakers.groovy" // default destination // when the datastore is not available to "/unavailable.gtpl" on DATASTORE not ENABLED // show some maintenance is upcoming to "/speakers.groovy?maintenance=true" on DATASTORE \ is SCHEDULED_MAINTENANCE}

jeudi 19 mai 2011

Page 59: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Capabilities

• Google App Engine allows you to know the status and availability of the various services–DATASTORE, DATESTORE_WRITE, MEMCACHE...–ENABLED, DISABLED, UNKNOWN,

SCHEDULED_MAINTENANCE–is() and not() methods

37

if (capabilities[DATASTORE_WRITE].is(ENABLED)) { // write some content in the datastore} else { // otherwise, redirect to some maintenance page}

jeudi 19 mai 2011

Page 60: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Task queue API

// access a configured queue using the subscript notationqueues['dailyEmailQueue'] // or using the property access notationqueues.dailyEmailQueue // you can also access the default queue with:queues.defaultdefaultQueue

// add a task to the queuequeue << [ countdownMillis: 1000, url: "/task/dailyEmail", taskName: "sendDailyEmailNewsletter", method: 'PUT', params: [date: '20090914'], payload: content]

38jeudi 19 mai 2011

Page 61: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Jabber / XMPP support (1/3)

• Sending instant messages

String recipient = "[email protected]" // check if the user is onlineif (xmpp.getPresence(recipient).isAvailable()) { // send the message def status = xmpp.send(to: recipient, body: "Hello, how are you?")  // checks the message was successfully // delivered to all the recipients assert status.isSuccessful()}

39jeudi 19 mai 2011

Page 62: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Jabber / XMPP support (2/3)

• Sending instant messages with an XML payload

String recipient = "[email protected]" // check if the service is onlineif (xmpp.getPresence(recipient).isAvailable()) { // send the message def status = xmpp.send(to: recipient, xml: { customers { customer(id: 1) { name 'Google' } } })  // checks the message was successfully delivered to the service assert status.isSuccessful()}

40jeudi 19 mai 2011

Page 63: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Jabber / XMPP support (2/3)

• Sending instant messages with an XML payload

String recipient = "[email protected]" // check if the service is onlineif (xmpp.getPresence(recipient).isAvailable()) { // send the message def status = xmpp.send(to: recipient, xml: { customers { customer(id: 1) { name 'Google' } } })  // checks the message was successfully delivered to the service assert status.isSuccessful()}

<customers> <customer id=’1’> <name>Google</name>

</customer></customers>

40jeudi 19 mai 2011

Page 64: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Jabber / XMPP support (3/3)

• Receving incoming instant messages–Once you’ve configured a route for jabber messages–Add the inbound message service in appengine-web.xml

def message = xmpp.parseMessage(request)// get the body of the messagemessage.body// get the sender Jabber IDmessage.from// get the list of recipients Jabber IDsmessage.recipients // if the message is an XML document instead of a raw string messageif (message.isXml()) { // get the raw XML message.stanza // get a document parsed with XmlSlurper message.xml}

41jeudi 19 mai 2011

Page 65: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Memcache service

• Map notation access to the cache

class Country implements Serialzable { String name } def countryFr = new Country(name: 'France') // use the subscript notation to put a country object in the cache

// (you can also use non-string keys)memcache['FR'] = countryFr // check that a key is present in the cacheif ('FR' in memcache) { // use the subscript notation to get an entry from the cache using a key

def countryFromCache = memcache['FR']}

42jeudi 19 mai 2011

Page 66: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Closure memoization

• Cache the return values for each dinstinct invocation (for a given arguments set)

43

def countEntities = memcache.memoize { String kind -> datastore.prepare( new Query(kind) ) .countEntities()}

// first calldef totalPics = countEntityes('photos')

// second call, hitting the cachetotalPics = countEntityes('photos')

jeudi 19 mai 2011

Page 67: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Blobstore enhancements

• The blobstore allows to store some large content–images, videos, etc.

44

def blob = ...print blob.filename // contentType, creation, size

// output the content of the blob to the responseblob.serve response

// read the content of the blobblob.withReader { Reader r -> ... }blob.withStream { InputStream is -> ... }

// delete the blobblob.delete()

jeudi 19 mai 2011

Page 68: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

File service

• The file service provides a file-like read/write access over blobs from the blobstore services–programmatic creation of blobs was an issue before

45

def file = files.createNewBlobFile("text/plain", "hello.txt")

// writing with a writerfile.withWriter { writer ‐>    writer << "some content"}

// writing binary contentfile.withOutputStream { stream ‐>    stream << "some content".bytes}

// file.withWriter(encoding: "US‐ASCII")

// file.withWriter(locked: false, finalize: false)

jeudi 19 mai 2011

Page 69: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

File service

• Instead of using the blobstore reading capabilities, you can read from the file service

46

// read from a buffered input stream

file.withInputStream { BufferedInputStream stream ‐>

    // read from the stream}

// read from a buffered reader

file.withReader{ BufferedReader reader ‐>

    // read from the reader}

// locked and encoding params available too

jeudi 19 mai 2011

Page 70: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Images service

• Readable DSL for manipulating images

47

def blobKey = ...

def image = blobKey.image.transform { resize 1600, 1200 crop 0.1, 0.1, 0.9, 0.9 horizontal flip // vertical flip too rotate 90 feeling lucky // image corrections}

def thumbnail = image.resize(100, 100)

jeudi 19 mai 2011

Page 71: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Channel Service

• For Comet-style applications

• Then in the view, in JavaScript...

48

def token = channel.createChannel('clientID')channel.send 'clientID', 'Hi!'

channel = new goog.appengine.Channel(token);socket = channel.open();socket.onmessage = function(msg) { ... }

jeudi 19 mai 2011

Page 72: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Simple plugin system

• Gaelyk features a simple plugin system for extending your apps and share commonalities

• A plugin lets you–provide additional groovlets and templates–contribute new URL routes–add new categories–define variables in the binding–override existing binding variables–provide any static content–add new libraries–do any initialization–add before/after request hooks

49jeudi 19 mai 2011

Page 73: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Simple plugin system

• A plugin is actually just a zip file!–Basically, just a Gaelyk application, minus...

•the Groovy / Gaelyk / GAE JARs•the web.xml and appengine-web.xml descriptors

–But with a /WEB-INF/plugins/myplugin.groovy descriptor

• A plugin must be referenced in /WEB-INF/plugins.groovy with–install myplugin

•shortcut to /WEB-INF/plugins/myplugin.groovy

50jeudi 19 mai 2011

Page 74: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Simple plugin system

• An example plugin descriptor–/WEB-INF/plugins/jsonPlugin.groovy

import net.sf.json.groovy.* // add new variables in the bindingbinding {

jsonLibVersion = "2.3"          // a simple string variable

json = new JsonGroovyBuilder()  // 3rd party class

} // add new routes with the usual routing system format

routes {get "/json", forward: "/json.groovy"

} // install a category you've developped

categories jsonlib.JsonlibCategory

before { req, resp ‐> ... } // or after

 // any other initialization code you'd need

51jeudi 19 mai 2011

Page 75: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Summary

• Easy access to a cloud solution–Deploying Java apps, as easily as you would with PHP

• Familiar to Java folks–Your good old Servlet centric webapps style

• Free tier

• Gaelyk provides a simplified approach to creating Servlet centric webapps in a productive manner–Leveraging Groovy’s servlet / template support

and dynamic capabilities

52jeudi 19 mai 2011

Page 76: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

What’s coming next?

• Expect more sugar around the Datastore–An SQL-like query DSL

• Testing facilities specific to Gaelyk–testing utility class, Spock-specific ones...

• Anything that’ll come up in newer GAE SDK versions–in particular, Full Text Search!

53jeudi 19 mai 2011

Page 77: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Not only me...

Benjamin Muschko

Gradle GAE pluginGradle Gaelyk pluginGaelyk datastore viewer plugin

54

Vladimír Orany

Gradle Gaelyk Eclipse pluginTDD Gaelyk template (w/ Spock & Easyb integration)Eclipse DSLD file

Marco Vermeulen

Spock testing integration

jeudi 19 mai 2011

Page 78: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Europe 2011 — Copenhagen, Denmark

One more thing...

jeudi 19 mai 2011

Page 79: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

CloudFoundry Gaelyk variant

56jeudi 19 mai 2011

Page 80: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

CloudFoundry Gaelyk variant

57

Vaporware

jeudi 19 mai 2011

Page 82: Gaelyk - Guillaume Laforge - GR8Conf Europe 2011

Image credits

• Speed limit : http://www.morguefile.com/archive/display/18492Warehouse : http://www.morguefile.com/archive/display/85628Check mark: http://www.lnl.infn.it/~epics/WikiDumps/localhost/600px-symbol_ok.svg.pngPuzzle: http://www.everystockphoto.com/photo.php?imageId=263521Light bulb: https://newsline.llnl.gov/retooling/mar/03.28.08_images/lightBulb.pngWeight balance: http://www.medicalscale1.com/wp-content/uploads/2010/11/balance-weight-scale2.jpgClouds http://www.morguefile.com/archive/display/627059http://www.morguefile.com/archive/display/625552http://www.morguefile.com/archive/display/629785Duke ok GAE http://weblogs.java.net/blog/felipegaucho/archive/ae_gwt_java.pngPython logo : http://python.org/images/python-logo.gifGaelic cross with clouds : http://www.morguefile.com/archive/display/37889Snow foot steps : http://www.flickr.com/photos/robinvanmourik/2875929243/Sugar : http://www.flickr.com/photos/ayelie/441101223/sizes/l/Press release: http://www.napleswebdesign.net/wp-content/uploads/2009/06/press_release_11.jpgSteve Jobs http://blogs.lentreprise.com/auto-entrepreneur/wp-content/blogs.dir/233/files/2010/07/Steve_Jobs_WWDC07.jpgDuke Nukem Forever http://img.jeuxvideo.fr/photo/00704014-photo-duke-nukem-forever.jpg

59jeudi 19 mai 2011