SlideShare a Scribd company logo
1 of 61
Download to read offline
Chicago, October 19 - 22, 2010




              a lightweight Groovy toolkit
              for Google App Engine
              Guillaume Laforge — SpringSource




mercredi 20 octobre 2010
Guillaume Laforge

       • Groovy Project Manager
       • JSR-241 Spec Lead
       • Head of Groovy Development
         at SpringSource
       • Initiator of the Grails framework
       • Founder of the Gaelyk toolkit
       • Co-author of Groovy in Action

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


                           2
mercredi 20 octobre 2010
Bug killer... real insects with legs!

       • Thanks to Groovy, with one hand left for coding,
         I’m still more productive than with Java!




                           3
mercredi 20 octobre 2010
Bug killer... real insects with legs!

       • Thanks to Groovy, with one hand left for coding,
         I’m still more productive than with Java!




                           3
mercredi 20 octobre 2010
Cloud
  Computing
mercredi 20 octobre 2010
IaaS, PaaS, SaaS


       • Software as a Service
             – Gmail, SalesForce.com
                                       SaaS
       • Platform as a Service
             – Google App Engine       PaaS
       • Infrastructure as a Service
             – Amazon EC2              IaaS
                           5
mercredi 20 octobre 2010
IaaS, PaaS, SaaS


       • Software as a Service
             – Gmail, SalesForce.com
                                       SaaS
       • Platform as a Service
             – Google App Engine       PaaS
       • Infrastructure as a Service
             – Amazon EC2              IaaS
                           5
mercredi 20 octobre 2010
IaaS, PaaS, SaaS


       • Software as a Service
             – Gmail, SalesForce.com
                                       SaaS
       • Platform as a Service
             – Google App Engine       PaaS
       • Infrastructure as a Service
             – Amazon EC2              IaaS
                           5
mercredi 20 octobre 2010
Google App Engine

       •   Google’s PaaS solution
       •   Run your app on Google’s infrastructure
       •   Initially just Python supported
       •   1+ year ago, Java supported added too
             – Sandboxed JVM
             – Jetty servlet container


       • Several JVM-compatible language supported

       • A few services available
             – Email, XMPP, URL Fetch, Image, User, Task queues...


                           6
mercredi 20 octobre 2010
Key aspects

       • You can use most of your usual web frameworks for
         developping apps on App Engine Java
             – A WAR file, basically!
             – 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

                           7
mercredi 20 octobre 2010
Available services

       • Memcache                            – Send / receive Jabber
             – JCache implementation           messages (GTalk)
             – Save on CPU and DB          • User
                                             – Use Google’s user/
       • URL Fetch                             authentication system
             – Access remote resources       – OAuth support
             – HttpUrlConnection
                                           • Cron & Task queues
       • Mail                                – Schedule tasks at regular
             – Support both incoming and       intervals
               outgoing emails               – Queue units of work
       • Images                            • Blobstore
             – Resize, crop, rotate...       – For storing large content
       • XMPP                              • And much more...

                           8
mercredi 20 octobre 2010
Limitations

       • Not our usual relational database
             – key / value datastore
       • 30 seconds request duration limit
       • 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

                           9
mercredi 20 octobre 2010
Quotas




                           10
mercredi 20 octobre 2010
Quotas (1/2)

       • Bandwidth                   • Mail
             – 1,3M requests/day       – 7K calls/day
             – 1GB/day in/out          – 2K recepients/day
             – 6.5 CPU hours/day       – 5K emails/day
                                       – 2K attachments
       • Datastore                     – 100MB of attachments
             – 10M calls
             – 1GB/day               • URL Fetch
             – 12GB in / 115GB out     – 657K calls/day
             – 60 CPU hours/day        – 4GB in/out /day




                           11
mercredi 20 octobre 2010
Quotas (2/2)

       • XMPP                        • Memcache
             – 657K calls/day          – 8.6M calls/day
             – 4GB data sent/day       – 10GB in
             – 657K recepients/day     – 50GB out
             – 1MB invitations/day
                                     • Task queues
       • Image manipulation            – 100K calls
          – 864 calls/day
          – 1GB in / 5GB out
          – 2.5M transforms




                           12
mercredi 20 octobre 2010
Quotas (2/2)

       • XMPP                        • Memcache
             – 657K calls/day          – 8.6M calls/day
             – 4GB data sent/day       – 10GB in
             – 657K recepients/day     – 50GB out
             – 1MB invitations/day
                                     • Task queues
       • Image manipulation            – 100K calls
          – 864 calls/day
                                                          ur es
          – 1GB in / 5GB out                           fig
          – 2.5M transforms                    at ed
                                          u td
                                       O

                           12
mercredi 20 octobre 2010
The Datastore




mercredi 20 octobre 2010
The datastore...

       • It’s not your father’s relational database! «NoSQL»

       • 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

                           14
mercredi 20 octobre 2010
...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


                           15
mercredi 20 octobre 2010
Nice dashboard

mercredi 20 octobre 2010
http://gaelyk.appspot.com




mercredi 20 octobre 2010
                                   F
http://gaelyk.appspot.com




mercredi 20 octobre 2010
                                   F
0 .5.6
                           with Ca pabilities and         g
                           Namespace a    ware URL routin




                    18              SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.

mercredi 20 octobre 2010
19     SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.

mercredi 20 octobre 2010
Gaelyk

       • 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



                           20
mercredi 20 octobre 2010
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

       • The truth: We worked with the Google App Engine Java
         team before the official launch of the platform, to ensure
         Groovy would run well on this new environment, and
         Gaelyk emerged from our test-bed project, and people
         asked me to Open-Source it!

                           21
mercredi 20 octobre 2010
First steps...



 • Go to http://gaelyk.appspot.com
 • Download the template project
 • Put your first Groovlet in /WEB-INF/groovy
 • And your templates at the root
 • And you’re ready to go!
 • Launch dev_appserver.sh
 • Go to http://localhost:8080/
mercredi 20 octobre 2010
The web.xml
                                                                                      ">
                      <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5
                        <servlet>
                           <servlet-name>GroovletServlet</servlet-name>
                           <servlet-class>groovyx.gaelyk.GaelykServlet</servlet-class>
                        </servlet>
                           <servlet>
                           <servlet-name>TemplateServlet</servlet-name>
                                                                                        -class>
                           <servlet-class>groovyx.gaelyk.GaelykTemplateServlet</servlet
                         </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>
                         <welcome-file-list>
                            <welcome-file>index.gtpl</welcome-file>
                         </welcome-file-list>
                       </web-app>




                           23
mercredi 20 octobre 2010
MVC: Groovlets and templates



                                 Groovlets                  Templates
                                (controllers)                 (views)




                                                 Entities
                                                (domain)




                           24
mercredi 20 octobre 2010
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
                                    }
                                }




                           25
mercredi 20 octobre 2010
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>



                           26
mercredi 20 octobre 2010
Shortcuts

     • Google services           • Variables available
       – datastore                 – request / response
       – blobstore                 – context / application
       – memcache                  – sessions
       – capabilities              – params / headers
       – images                    – out / sout / html
       – urlFetch                  – localMode / app.*
       – mail
       – userService / user      • Methods available
       – defaultQueue / queues     – include / forward / redirect
       – xmpp                      – println / print
       – namespace

                           27
mercredi 20 octobre 2010
Demo




                                  SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.

mercredi 20 octobre 2010
Groovy sugar!




mercredi 20 octobre 2010
Sending emails with Gaelyk




                     mail.send to:   'foobar@gmail.com',
                             from:   'other@gmail.com',
                          subject:   'Hello World',
                         htmlBody:   '<bold>Hello</bold>'




                           30
mercredi 20 octobre 2010
...compared to Java


    Properties props = new Properties();
                                                     ops, null);
    Ses sion session = Session.getDefaultInstance(pr

     String msgBody = "...";

     try {
         Message msg = new MimeMessage(session);
                                                            m", "Admin"));
         msg.se tFrom(new InternetAddress("admin@example.co
                                                 TO,
         msg.addRecipient(Message.RecipientType.                    "Mr. User"));
                           new InternetAddress("user@example.com",
                                                           n activated");
         msg .setSubject("Your Example.com account has bee
         msg.setText(msgBody);
         Transport.send(msg);
     } catch (AddressException e) {}
     } catch (MessagingException e) {}




                           31
mercredi 20 octobre 2010
Accessing the datastore

       • Direct interaction with the low-level datastore API
                                                                               ty
                                import com.google.appengine.api.datastore.Enti
                                 
                                Entity entity = new Entity("person")
                                 
                                                                             map
                                // subscript notation, like when accessing a
                                entity['name'] = "Guillaume Laforge"
                                 
                                // normal property access notation
                                entity.age = 32

                                entity.save()
                                entity.delete()

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




                           32
mercredi 20 octobre 2010
Querying to be improved...

                   import com.google.appengine.api.datastore.*
                                                                                      der.*
                   import static com.google.appengine.api.datastore.FetchOptions.Buil
                    
                   // query the scripts stored in the datastore
                   def query = new Query("savedscript")
                    
                   // sort results by descending order of the creation date
                   query.addSort("dateCreated", Query.SortDirection.DESCENDING)
                    
                                                                                     author
                   // filters the entities so as to return only scripts by a certain
                                                                                      r)
                   query.addFilter("author", Query.FilterOperator.EQUAL, params.autho
                    
                   PreparedQuery preparedQuery = datastore.prepare(query)
                    
                   // return only the first 10 results
                   def entities = preparedQuery.asList( withLimit(10) )




                           33
mercredi 20 octobre 2010
...into something groovier?



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




                           34
mercredi 20 octobre 2010
...into something groovier?



                                def entities = datastore.query {
                                    select all from savedscript
                                    sort desc by dateCreated
                                    where author == params.author
                                    limit 10                         te d!
                                } as List                       m en
                                                              ple
                                                      et   Im
                                                  o tY
                                                N


                           34
mercredi 20 octobre 2010
Task queue API

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

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



                           35
mercredi 20 octobre 2010
Jabber / XMPP support (1/3)

       • Sending instant messages

                 String recipient = "someone@gmail.com"
                  
                 // check if the user is online
                 if (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()
                  }



                           36
mercredi 20 octobre 2010
Jabber / XMPP support (2/3)

       • Sending instant messages with an XML payload
                 String recipient = "service@gmail.com"
                  
                 // check if the service is online
                 if (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()
                  }



                           37
mercredi 20 octobre 2010
Jabber / XMPP support (2/3)

       • Sending instant messages with an XML payload
                 String recipient = "service@gmail.com"
                  
                 // check if the service is online
                 if (xmpp.getPresence(recipient).isAvailable()) {
                     // send the message
                     def status = xmpp.send(to: recipient, xml: {
                         customers {
                             customer(id: 1) {              <customers>
                                 name 'Google'                  <customer id=’1’>
                             }                                      <name>Google</name>
                         }                                      </customer>
                                                            </customers>
                     })
                  
                     // checks the message was successfully delivered to the service
                     assert status.isSuccessful()
                  }



                           37
mercredi 20 octobre 2010
Jabber / XMPP support (3/3)

       • Receving incoming instant messages
             – Configure the XmppServlet in web.xml
             – Add the inbound message service in appengine-web.xml

                  // get the body of the message
                  message.body
                  // get the sender Jabber ID
                  message.from
                  // get the list of recipients Jabber IDs
                  message.recipients
                   
                  // if the message is an XML document instead of a raw string message
                  if (message.isXml()) {
                      // get the raw XML
                      message.stanza
                      // get a document parsed with XmlSlurper
                      message.xml
                  }


                           38
mercredi 20 octobre 2010
Memcache service

       • Map notation access to the cache


                                                              }
           class Country implements Serialzable { String name
            
           def countryFr = new Country(name: 'France')
            
                                                                 in the cache
           // use the subscript notation to put a country object
           // (you can also use non-string keys)
           memcache['FR'] = countryFr
            
           // check that a key is present in the cache
           if ('FR' in memcache) {
                                                                  the cache using a key
               // use the subscript notation to get an entry from
               def countryFromCache = memcache['FR']
            }




                           39
mercredi 20 octobre 2010
Closure memoization

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

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

                // first call
                def totalPics = countEntityes('photos')

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



                           40
mercredi 20 octobre 2010
Blobstore enhancements

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

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

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

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

              // delete the blob
              blob.delete()
                           41
mercredi 20 octobre 2010
Images service

       • Readable DSL for manipulating images

                      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)



                           42
mercredi 20 octobre 2010
Capabilities

       • Google App Engine allows you to know the status and
         availability of the various services
             – DATASTORE, DATESTORE_WRITE, MEMCACHE, etc.
             – ENABLED, DISABLED, UNKNOWN,
               SCHEDULED_MAINTENANCE
             – is() and not() methods


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



                           43
mercredi 20 octobre 2010
URL Routing system (1/2)

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

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

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

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

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




                           44
mercredi 20 octobre 2010
URL Routing system (2/2)

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

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

                                                                 es status
           // different destinations depending on the GAE servic
           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
            }


                           45
mercredi 20 octobre 2010
Simple plugin system (1/3)

     • Gaelyk 0.4 introduced 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
           – provide any static content
           – add new libraries
           – do any initialization



                           46
mercredi 20 octobre 2010
Simple plugin system (2/3)

     • 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




                           47
mercredi 20 octobre 2010
Simple plugin system (3/3)

     • An example plugin descriptor
           – /WEB-INF/plugins/jsonPlugin.groovy
             import net.sf.json.*
             import net.sf.json.groovy.*
              
             // add new variables in the binding
             binding {
                                                                           le
                 jsonLibVersion = "2.3"          // a simple string variab
                                                                            of a 3rd‐party JAR
                 json = new JsonGroovyBuilder()  // an instance of a 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
               
              // any other initialization code you'd need



                           48
mercredi 20 octobre 2010
Summary




                            SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.

mercredi 20 octobre 2010
What’s coming next?

     • Gaelyk 0.5.5 released a week ago with additional URL
       routing support (capabilities, namespace)
           – and a 0.5.6 bug fix this past weekend


     • Expect more sugar around the Datastore
                 • An SQL-like query DSL
                 • Easier relationship management (builder)


     • Perhaps pre-compiled groovlets and templates

     • More generally...
           – Anything that’ll come up in upcoming GAE SDK versions

                           50
mercredi 20 octobre 2010
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

     • Pretty cheap
           – You need a high-trafficed website to reach the quotas

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


                           51
mercredi 20 octobre 2010
Q&A




                                 SpringOne 2GX 2010. All rights reserved. Do not distribute without permission.

mercredi 20 octobre 2010
Thanks for your attention!




                                      e
                              e Laforg velopment
                   Gu illaum oovy De         m
                          of Gr e@gmail.co
                   Head laforg
                    E mail: g glaforge
                              @
                    T witter:

                                                   • References:
                                                     • http://gaelyk.appspot.com/
                                                     • http://groovy.codehaus.org/
                                                     • http://code.google.com/appengine/



                           53
mercredi 20 octobre 2010
Images used in this presentation

           Bandage http://image.made-in-china.com/2f0j00fIGaTPEYDQnB/Elastic-Crepe-Bandage-Gauze-.jpg
           RIP http://gipsydan.files.wordpress.com/2009/11/rip.jpg
           Puzzle: http://www.everystockphoto.com/photo.php?imageId=263521
           Light bulb: https://newsline.llnl.gov/retooling/mar/03.28.08_images/lightBulb.png
           Clouds http://www.morguefile.com/archive/display/627059
           http://www.morguefile.com/archive/display/625552
           http://www.morguefile.com/archive/display/629785
           Duke ok GAE http://weblogs.java.net/blog/felipegaucho/archive/ae_gwt_java.png
           Python logo : http://python.org/images/python-logo.gif
           Gaelyc cross with clouds : http://www.morguefile.com/archive/display/37889
           Speed limit : http://www.morguefile.com/archive/display/18492
           Warehouse : http://www.morguefile.com/archive/display/85628
           Snow 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.jpg




                           54
mercredi 20 octobre 2010

More Related Content

What's hot

JavaScript Service Worker Design Patterns for Better User Experience
JavaScript Service Worker Design Patterns for Better User ExperienceJavaScript Service Worker Design Patterns for Better User Experience
JavaScript Service Worker Design Patterns for Better User Experiencereeder29
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet CampPuppet
 
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...Sencha
 
Node.js and couchbase Full Stack JSON - Munich NoSQL
Node.js and couchbase   Full Stack JSON - Munich NoSQLNode.js and couchbase   Full Stack JSON - Munich NoSQL
Node.js and couchbase Full Stack JSON - Munich NoSQLPhilipp Fehre
 
Building and Managing Projects with Maven
Building and Managing Projects with MavenBuilding and Managing Projects with Maven
Building and Managing Projects with MavenKhan625
 
Building and managing java projects with maven part-III
Building and managing java projects with maven part-IIIBuilding and managing java projects with maven part-III
Building and managing java projects with maven part-IIIprinceirfancivil
 
SenchaCon 2016: A Look Ahead: Survey Next-Gen Modern Browser APIs - Shikhir S...
SenchaCon 2016: A Look Ahead: Survey Next-Gen Modern Browser APIs - Shikhir S...SenchaCon 2016: A Look Ahead: Survey Next-Gen Modern Browser APIs - Shikhir S...
SenchaCon 2016: A Look Ahead: Survey Next-Gen Modern Browser APIs - Shikhir S...Sencha
 
Improve WordPress performance with caching and deferred execution of code
Improve WordPress performance with caching and deferred execution of codeImprove WordPress performance with caching and deferred execution of code
Improve WordPress performance with caching and deferred execution of codeDanilo Ercoli
 
Mobile Hybrid Development with WordPress
Mobile Hybrid Development with WordPressMobile Hybrid Development with WordPress
Mobile Hybrid Development with WordPressDanilo Ercoli
 
Exciting JavaScript - Part II
Exciting JavaScript - Part IIExciting JavaScript - Part II
Exciting JavaScript - Part IIEugene Lazutkin
 
WordPress Development Tools and Best Practices
WordPress Development Tools and Best PracticesWordPress Development Tools and Best Practices
WordPress Development Tools and Best PracticesDanilo Ercoli
 
Atlanta JUG - Integrating Spring Batch and Spring Integration
Atlanta JUG - Integrating Spring Batch and Spring IntegrationAtlanta JUG - Integrating Spring Batch and Spring Integration
Atlanta JUG - Integrating Spring Batch and Spring IntegrationGunnar Hillert
 
Optimization of modern web applications
Optimization of modern web applicationsOptimization of modern web applications
Optimization of modern web applicationsEugene Lazutkin
 
Here Be Dragons - Debugging WordPress
Here Be Dragons - Debugging WordPressHere Be Dragons - Debugging WordPress
Here Be Dragons - Debugging WordPressRami Sayar
 
Getting started with rails active storage wae
Getting started with rails active storage waeGetting started with rails active storage wae
Getting started with rails active storage waeBishal Khanal
 
Padrino - the Godfather of Sinatra
Padrino - the Godfather of SinatraPadrino - the Godfather of Sinatra
Padrino - the Godfather of SinatraStoyan Zhekov
 
RESTful Api practices Rails 3
RESTful Api practices Rails 3RESTful Api practices Rails 3
RESTful Api practices Rails 3Anton Narusberg
 
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra  SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra Sencha
 
OSGi, Scripting and REST, Building Webapps With Apache Sling
OSGi, Scripting and REST, Building Webapps With Apache SlingOSGi, Scripting and REST, Building Webapps With Apache Sling
OSGi, Scripting and REST, Building Webapps With Apache SlingCarsten Ziegeler
 

What's hot (20)

JavaScript Service Worker Design Patterns for Better User Experience
JavaScript Service Worker Design Patterns for Better User ExperienceJavaScript Service Worker Design Patterns for Better User Experience
JavaScript Service Worker Design Patterns for Better User Experience
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
 
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...
 
Node.js and couchbase Full Stack JSON - Munich NoSQL
Node.js and couchbase   Full Stack JSON - Munich NoSQLNode.js and couchbase   Full Stack JSON - Munich NoSQL
Node.js and couchbase Full Stack JSON - Munich NoSQL
 
Building and Managing Projects with Maven
Building and Managing Projects with MavenBuilding and Managing Projects with Maven
Building and Managing Projects with Maven
 
Building and managing java projects with maven part-III
Building and managing java projects with maven part-IIIBuilding and managing java projects with maven part-III
Building and managing java projects with maven part-III
 
SenchaCon 2016: A Look Ahead: Survey Next-Gen Modern Browser APIs - Shikhir S...
SenchaCon 2016: A Look Ahead: Survey Next-Gen Modern Browser APIs - Shikhir S...SenchaCon 2016: A Look Ahead: Survey Next-Gen Modern Browser APIs - Shikhir S...
SenchaCon 2016: A Look Ahead: Survey Next-Gen Modern Browser APIs - Shikhir S...
 
Improve WordPress performance with caching and deferred execution of code
Improve WordPress performance with caching and deferred execution of codeImprove WordPress performance with caching and deferred execution of code
Improve WordPress performance with caching and deferred execution of code
 
Mobile Hybrid Development with WordPress
Mobile Hybrid Development with WordPressMobile Hybrid Development with WordPress
Mobile Hybrid Development with WordPress
 
Exciting JavaScript - Part II
Exciting JavaScript - Part IIExciting JavaScript - Part II
Exciting JavaScript - Part II
 
WordPress Development Tools and Best Practices
WordPress Development Tools and Best PracticesWordPress Development Tools and Best Practices
WordPress Development Tools and Best Practices
 
Atlanta JUG - Integrating Spring Batch and Spring Integration
Atlanta JUG - Integrating Spring Batch and Spring IntegrationAtlanta JUG - Integrating Spring Batch and Spring Integration
Atlanta JUG - Integrating Spring Batch and Spring Integration
 
Optimization of modern web applications
Optimization of modern web applicationsOptimization of modern web applications
Optimization of modern web applications
 
Here Be Dragons - Debugging WordPress
Here Be Dragons - Debugging WordPressHere Be Dragons - Debugging WordPress
Here Be Dragons - Debugging WordPress
 
Getting started with rails active storage wae
Getting started with rails active storage waeGetting started with rails active storage wae
Getting started with rails active storage wae
 
Padrino - the Godfather of Sinatra
Padrino - the Godfather of SinatraPadrino - the Godfather of Sinatra
Padrino - the Godfather of Sinatra
 
RESTful Api practices Rails 3
RESTful Api practices Rails 3RESTful Api practices Rails 3
RESTful Api practices Rails 3
 
SOA on Rails
SOA on RailsSOA on Rails
SOA on Rails
 
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra  SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra
 
OSGi, Scripting and REST, Building Webapps With Apache Sling
OSGi, Scripting and REST, Building Webapps With Apache SlingOSGi, Scripting and REST, Building Webapps With Apache Sling
OSGi, Scripting and REST, Building Webapps With Apache Sling
 

Viewers also liked

Groovy to infinity and beyond - SpringOne2GX - 2010 - Guillaume Laforge
Groovy to infinity and beyond - SpringOne2GX - 2010 - Guillaume LaforgeGroovy to infinity and beyond - SpringOne2GX - 2010 - Guillaume Laforge
Groovy to infinity and beyond - SpringOne2GX - 2010 - Guillaume LaforgeGuillaume Laforge
 
Practical Groovy Domain-Specific Languages - Guillaume Laforge - Usi 2009
Practical Groovy Domain-Specific Languages - Guillaume Laforge - Usi 2009Practical Groovy Domain-Specific Languages - Guillaume Laforge - Usi 2009
Practical Groovy Domain-Specific Languages - Guillaume Laforge - Usi 2009Guillaume Laforge
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Guillaume Laforge
 
Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Guillaume Laforge
 
Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Guillaume Laforge
 

Viewers also liked (7)

Groovy to infinity and beyond - SpringOne2GX - 2010 - Guillaume Laforge
Groovy to infinity and beyond - SpringOne2GX - 2010 - Guillaume LaforgeGroovy to infinity and beyond - SpringOne2GX - 2010 - Guillaume Laforge
Groovy to infinity and beyond - SpringOne2GX - 2010 - Guillaume Laforge
 
Practical Groovy Domain-Specific Languages - Guillaume Laforge - Usi 2009
Practical Groovy Domain-Specific Languages - Guillaume Laforge - Usi 2009Practical Groovy Domain-Specific Languages - Guillaume Laforge - Usi 2009
Practical Groovy Domain-Specific Languages - Guillaume Laforge - Usi 2009
 
Whats New In Groovy 1.6?
Whats New In Groovy 1.6?Whats New In Groovy 1.6?
Whats New In Groovy 1.6?
 
Groovy 2 and beyond
Groovy 2 and beyondGroovy 2 and beyond
Groovy 2 and beyond
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013
 
Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013
 
Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013
 

Similar to Gaelyk - SpringOne2GX - 2010 - Guillaume Laforge

Red Dirt Ruby Conference
Red Dirt Ruby ConferenceRed Dirt Ruby Conference
Red Dirt Ruby ConferenceJohn Woodell
 
Gaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
Gaelyk - Groovy Grails eXchange 2010 - Guillaume LaforgeGaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
Gaelyk - Groovy Grails eXchange 2010 - Guillaume LaforgeGuillaume Laforge
 
Google App Engine, Groovy and Gaelyk presentation at the Paris JUG
Google App Engine, Groovy and Gaelyk presentation at the Paris JUGGoogle App Engine, Groovy and Gaelyk presentation at the Paris JUG
Google App Engine, Groovy and Gaelyk presentation at the Paris JUGGuillaume Laforge
 
Odnoklassniki.ru Architecture
Odnoklassniki.ru ArchitectureOdnoklassniki.ru Architecture
Odnoklassniki.ru ArchitectureDmitry Buzdin
 
Gaelyk - Paris GGUG 2011 - Guillaume Laforge
Gaelyk - Paris GGUG 2011 - Guillaume LaforgeGaelyk - Paris GGUG 2011 - Guillaume Laforge
Gaelyk - Paris GGUG 2011 - Guillaume LaforgeGuillaume Laforge
 
Aloha on-rails-2009
Aloha on-rails-2009Aloha on-rails-2009
Aloha on-rails-2009John Woodell
 
Big Bad PostgreSQL: BI on a Budget
Big Bad PostgreSQL: BI on a BudgetBig Bad PostgreSQL: BI on a Budget
Big Bad PostgreSQL: BI on a BudgetJoshua L. Davis
 
Chirp 2010: Scaling Twitter
Chirp 2010: Scaling TwitterChirp 2010: Scaling Twitter
Chirp 2010: Scaling TwitterJohn Adams
 
BRAINREPUBLIC - Powered by no-SQL
BRAINREPUBLIC - Powered by no-SQLBRAINREPUBLIC - Powered by no-SQL
BRAINREPUBLIC - Powered by no-SQLAndreas Jung
 
Alex Wade, Digital Library Interoperability
Alex Wade, Digital Library InteroperabilityAlex Wade, Digital Library Interoperability
Alex Wade, Digital Library Interoperabilityparker01
 
Distributed Data processing in a Cloud
Distributed Data processing in a CloudDistributed Data processing in a Cloud
Distributed Data processing in a Cloudelliando dias
 
Implementing MongoDB at Shutterfly (Kenny Gorman)
Implementing MongoDB at Shutterfly (Kenny Gorman)Implementing MongoDB at Shutterfly (Kenny Gorman)
Implementing MongoDB at Shutterfly (Kenny Gorman)MongoSF
 

Similar to Gaelyk - SpringOne2GX - 2010 - Guillaume Laforge (20)

Red Dirt Ruby Conference
Red Dirt Ruby ConferenceRed Dirt Ruby Conference
Red Dirt Ruby Conference
 
App Engine Meetup
App Engine MeetupApp Engine Meetup
App Engine Meetup
 
Railsconf 2010
Railsconf 2010Railsconf 2010
Railsconf 2010
 
Oscon 2010
Oscon 2010Oscon 2010
Oscon 2010
 
Gaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
Gaelyk - Groovy Grails eXchange 2010 - Guillaume LaforgeGaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
Gaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
 
Google App Engine, Groovy and Gaelyk presentation at the Paris JUG
Google App Engine, Groovy and Gaelyk presentation at the Paris JUGGoogle App Engine, Groovy and Gaelyk presentation at the Paris JUG
Google App Engine, Groovy and Gaelyk presentation at the Paris JUG
 
Odnoklassniki.ru Architecture
Odnoklassniki.ru ArchitectureOdnoklassniki.ru Architecture
Odnoklassniki.ru Architecture
 
Gaelyk - Paris GGUG 2011 - Guillaume Laforge
Gaelyk - Paris GGUG 2011 - Guillaume LaforgeGaelyk - Paris GGUG 2011 - Guillaume Laforge
Gaelyk - Paris GGUG 2011 - Guillaume Laforge
 
Stackato v2
Stackato v2Stackato v2
Stackato v2
 
Aloha on-rails-2009
Aloha on-rails-2009Aloha on-rails-2009
Aloha on-rails-2009
 
Slideshare presentation
Slideshare presentationSlideshare presentation
Slideshare presentation
 
Stackato v3
Stackato v3Stackato v3
Stackato v3
 
Stackato v4
Stackato v4Stackato v4
Stackato v4
 
Big Bad PostgreSQL: BI on a Budget
Big Bad PostgreSQL: BI on a BudgetBig Bad PostgreSQL: BI on a Budget
Big Bad PostgreSQL: BI on a Budget
 
Chirp 2010: Scaling Twitter
Chirp 2010: Scaling TwitterChirp 2010: Scaling Twitter
Chirp 2010: Scaling Twitter
 
Stackato v5
Stackato v5Stackato v5
Stackato v5
 
BRAINREPUBLIC - Powered by no-SQL
BRAINREPUBLIC - Powered by no-SQLBRAINREPUBLIC - Powered by no-SQL
BRAINREPUBLIC - Powered by no-SQL
 
Alex Wade, Digital Library Interoperability
Alex Wade, Digital Library InteroperabilityAlex Wade, Digital Library Interoperability
Alex Wade, Digital Library Interoperability
 
Distributed Data processing in a Cloud
Distributed Data processing in a CloudDistributed Data processing in a Cloud
Distributed Data processing in a Cloud
 
Implementing MongoDB at Shutterfly (Kenny Gorman)
Implementing MongoDB at Shutterfly (Kenny Gorman)Implementing MongoDB at Shutterfly (Kenny Gorman)
Implementing MongoDB at Shutterfly (Kenny Gorman)
 

More from Guillaume Laforge

Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012Guillaume Laforge
 
Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Guillaume Laforge
 
Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Guillaume Laforge
 
Groovy 1.8 et 2.0 au BreizhC@mp 2012
Groovy 1.8 et 2.0 au BreizhC@mp 2012Groovy 1.8 et 2.0 au BreizhC@mp 2012
Groovy 1.8 et 2.0 au BreizhC@mp 2012Guillaume Laforge
 
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Guillaume Laforge
 
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume LaforgeGroovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume LaforgeGuillaume Laforge
 
Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGuillaume Laforge
 
Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Guillaume Laforge
 
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011Guillaume Laforge
 
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGuillaume Laforge
 
Groovy Update - Guillaume Laforge - Greach 2011
Groovy Update - Guillaume Laforge - Greach 2011Groovy Update - Guillaume Laforge - Greach 2011
Groovy Update - Guillaume Laforge - Greach 2011Guillaume Laforge
 
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Guillaume Laforge
 
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Guillaume Laforge
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Guillaume Laforge
 
Cloud foundry intro with groovy
Cloud foundry intro with groovyCloud foundry intro with groovy
Cloud foundry intro with groovyGuillaume Laforge
 
Groovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume LaforgeGroovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume LaforgeGuillaume Laforge
 
Groovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume LaforgeGroovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume LaforgeGuillaume Laforge
 

More from Guillaume Laforge (20)

Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012
 
Groovy 2.0 webinar
Groovy 2.0 webinarGroovy 2.0 webinar
Groovy 2.0 webinar
 
Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012
 
Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012
 
JavaOne 2012 Groovy update
JavaOne 2012 Groovy updateJavaOne 2012 Groovy update
JavaOne 2012 Groovy update
 
Groovy 1.8 et 2.0 au BreizhC@mp 2012
Groovy 1.8 et 2.0 au BreizhC@mp 2012Groovy 1.8 et 2.0 au BreizhC@mp 2012
Groovy 1.8 et 2.0 au BreizhC@mp 2012
 
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
 
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume LaforgeGroovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
 
Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific Languages
 
Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012
 
Whats new in Groovy 2.0?
Whats new in Groovy 2.0?Whats new in Groovy 2.0?
Whats new in Groovy 2.0?
 
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
 
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
 
Groovy Update - Guillaume Laforge - Greach 2011
Groovy Update - Guillaume Laforge - Greach 2011Groovy Update - Guillaume Laforge - Greach 2011
Groovy Update - Guillaume Laforge - Greach 2011
 
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
 
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
 
Cloud foundry intro with groovy
Cloud foundry intro with groovyCloud foundry intro with groovy
Cloud foundry intro with groovy
 
Groovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume LaforgeGroovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume Laforge
 
Groovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume LaforgeGroovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume Laforge
 

Recently uploaded

OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxMatsuo Lab
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8DianaGray10
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemAsko Soukka
 
99.99% of Your Traces Are (Probably) Trash (SRECon NA 2024).pdf
99.99% of Your Traces  Are (Probably) Trash (SRECon NA 2024).pdf99.99% of Your Traces  Are (Probably) Trash (SRECon NA 2024).pdf
99.99% of Your Traces Are (Probably) Trash (SRECon NA 2024).pdfPaige Cruz
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaborationbruanjhuli
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDELiveplex
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024D Cloud Solutions
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintMahmoud Rabie
 
IEEE Computer Society’s Strategic Activities and Products including SWEBOK Guide
IEEE Computer Society’s Strategic Activities and Products including SWEBOK GuideIEEE Computer Society’s Strategic Activities and Products including SWEBOK Guide
IEEE Computer Society’s Strategic Activities and Products including SWEBOK GuideHironori Washizaki
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfDianaGray10
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IES VE
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPathCommunity
 

Recently uploaded (20)

OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptx
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystem
 
99.99% of Your Traces Are (Probably) Trash (SRECon NA 2024).pdf
99.99% of Your Traces  Are (Probably) Trash (SRECon NA 2024).pdf99.99% of Your Traces  Are (Probably) Trash (SRECon NA 2024).pdf
99.99% of Your Traces Are (Probably) Trash (SRECon NA 2024).pdf
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership Blueprint
 
IEEE Computer Society’s Strategic Activities and Products including SWEBOK Guide
IEEE Computer Society’s Strategic Activities and Products including SWEBOK GuideIEEE Computer Society’s Strategic Activities and Products including SWEBOK Guide
IEEE Computer Society’s Strategic Activities and Products including SWEBOK Guide
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
 
20230104 - machine vision
20230104 - machine vision20230104 - machine vision
20230104 - machine vision
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation Developers
 

Gaelyk - SpringOne2GX - 2010 - Guillaume Laforge

  • 1. Chicago, October 19 - 22, 2010 a lightweight Groovy toolkit for Google App Engine Guillaume Laforge — SpringSource mercredi 20 octobre 2010
  • 2. Guillaume Laforge • Groovy Project Manager • JSR-241 Spec Lead • Head of Groovy Development at SpringSource • Initiator of the Grails framework • Founder of the Gaelyk toolkit • Co-author of Groovy in Action • Speaker: JavaOne, QCon, JavaZone, Sun TechDays, Devoxx, The Spring Experience, SpringOne2GX, JAX, Dynamic Language World, IJTC, and more... 2 mercredi 20 octobre 2010
  • 3. Bug killer... real insects with legs! • Thanks to Groovy, with one hand left for coding, I’m still more productive than with Java! 3 mercredi 20 octobre 2010
  • 4. Bug killer... real insects with legs! • Thanks to Groovy, with one hand left for coding, I’m still more productive than with Java! 3 mercredi 20 octobre 2010
  • 5. Cloud Computing mercredi 20 octobre 2010
  • 6. IaaS, PaaS, SaaS • Software as a Service – Gmail, SalesForce.com SaaS • Platform as a Service – Google App Engine PaaS • Infrastructure as a Service – Amazon EC2 IaaS 5 mercredi 20 octobre 2010
  • 7. IaaS, PaaS, SaaS • Software as a Service – Gmail, SalesForce.com SaaS • Platform as a Service – Google App Engine PaaS • Infrastructure as a Service – Amazon EC2 IaaS 5 mercredi 20 octobre 2010
  • 8. IaaS, PaaS, SaaS • Software as a Service – Gmail, SalesForce.com SaaS • Platform as a Service – Google App Engine PaaS • Infrastructure as a Service – Amazon EC2 IaaS 5 mercredi 20 octobre 2010
  • 9. Google App Engine • Google’s PaaS solution • Run your app on Google’s infrastructure • Initially just Python supported • 1+ year ago, Java supported added too – Sandboxed JVM – Jetty servlet container • Several JVM-compatible language supported • A few services available – Email, XMPP, URL Fetch, Image, User, Task queues... 6 mercredi 20 octobre 2010
  • 10. Key aspects • You can use most of your usual web frameworks for developping apps on App Engine Java – A WAR file, basically! – 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 7 mercredi 20 octobre 2010
  • 11. Available services • Memcache – Send / receive Jabber – JCache implementation messages (GTalk) – Save on CPU and DB • User – Use Google’s user/ • URL Fetch authentication system – Access remote resources – OAuth support – HttpUrlConnection • Cron & Task queues • Mail – Schedule tasks at regular – Support both incoming and intervals outgoing emails – Queue units of work • Images • Blobstore – Resize, crop, rotate... – For storing large content • XMPP • And much more... 8 mercredi 20 octobre 2010
  • 12. Limitations • Not our usual relational database – key / value datastore • 30 seconds request duration limit • 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 9 mercredi 20 octobre 2010
  • 13. Quotas 10 mercredi 20 octobre 2010
  • 14. Quotas (1/2) • Bandwidth • Mail – 1,3M requests/day – 7K calls/day – 1GB/day in/out – 2K recepients/day – 6.5 CPU hours/day – 5K emails/day – 2K attachments • Datastore – 100MB of attachments – 10M calls – 1GB/day • URL Fetch – 12GB in / 115GB out – 657K calls/day – 60 CPU hours/day – 4GB in/out /day 11 mercredi 20 octobre 2010
  • 15. Quotas (2/2) • XMPP • Memcache – 657K calls/day – 8.6M calls/day – 4GB data sent/day – 10GB in – 657K recepients/day – 50GB out – 1MB invitations/day • Task queues • Image manipulation – 100K calls – 864 calls/day – 1GB in / 5GB out – 2.5M transforms 12 mercredi 20 octobre 2010
  • 16. Quotas (2/2) • XMPP • Memcache – 657K calls/day – 8.6M calls/day – 4GB data sent/day – 10GB in – 657K recepients/day – 50GB out – 1MB invitations/day • Task queues • Image manipulation – 100K calls – 864 calls/day ur es – 1GB in / 5GB out fig – 2.5M transforms at ed u td O 12 mercredi 20 octobre 2010
  • 18. The datastore... • It’s not your father’s relational database! «NoSQL» • 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 14 mercredi 20 octobre 2010
  • 19. ...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 15 mercredi 20 octobre 2010
  • 23. 0 .5.6 with Ca pabilities and g Namespace a ware URL routin 18 SpringOne 2GX 2010. All rights reserved. Do not distribute without permission. mercredi 20 octobre 2010
  • 24. 19 SpringOne 2GX 2010. All rights reserved. Do not distribute without permission. mercredi 20 octobre 2010
  • 25. Gaelyk • 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 20 mercredi 20 octobre 2010
  • 26. 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 • The truth: We worked with the Google App Engine Java team before the official launch of the platform, to ensure Groovy would run well on this new environment, and Gaelyk emerged from our test-bed project, and people asked me to Open-Source it! 21 mercredi 20 octobre 2010
  • 27. First steps... • Go to http://gaelyk.appspot.com • Download the template project • Put your first Groovlet in /WEB-INF/groovy • And your templates at the root • And you’re ready to go! • Launch dev_appserver.sh • Go to http://localhost:8080/ mercredi 20 octobre 2010
  • 28. The web.xml "> <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5 <servlet> <servlet-name>GroovletServlet</servlet-name> <servlet-class>groovyx.gaelyk.GaelykServlet</servlet-class> </servlet> <servlet> <servlet-name>TemplateServlet</servlet-name> -class> <servlet-class>groovyx.gaelyk.GaelykTemplateServlet</servlet </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> <welcome-file-list> <welcome-file>index.gtpl</welcome-file> </welcome-file-list> </web-app> 23 mercredi 20 octobre 2010
  • 29. MVC: Groovlets and templates Groovlets Templates (controllers) (views) Entities (domain) 24 mercredi 20 octobre 2010
  • 30. 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 } } 25 mercredi 20 octobre 2010
  • 31. 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> 26 mercredi 20 octobre 2010
  • 32. Shortcuts • Google services • Variables available – datastore – request / response – blobstore – context / application – memcache – sessions – capabilities – params / headers – images – out / sout / html – urlFetch – localMode / app.* – mail – userService / user • Methods available – defaultQueue / queues – include / forward / redirect – xmpp – println / print – namespace 27 mercredi 20 octobre 2010
  • 33. Demo SpringOne 2GX 2010. All rights reserved. Do not distribute without permission. mercredi 20 octobre 2010
  • 35. Sending emails with Gaelyk mail.send to: 'foobar@gmail.com', from: 'other@gmail.com', subject: 'Hello World', htmlBody: '<bold>Hello</bold>' 30 mercredi 20 octobre 2010
  • 36. ...compared to Java Properties props = new Properties(); ops, null); Ses sion session = Session.getDefaultInstance(pr String msgBody = "..."; try { Message msg = new MimeMessage(session); m", "Admin"));     msg.se tFrom(new InternetAddress("admin@example.co TO,     msg.addRecipient(Message.RecipientType. "Mr. User"));                      new InternetAddress("user@example.com", n activated");     msg .setSubject("Your Example.com account has bee     msg.setText(msgBody);     Transport.send(msg); } catch (AddressException e) {} } catch (MessagingException e) {} 31 mercredi 20 octobre 2010
  • 37. Accessing the datastore • Direct interaction with the low-level datastore API ty import com.google.appengine.api.datastore.Enti   Entity entity = new Entity("person")   map // subscript notation, like when accessing a entity['name'] = "Guillaume Laforge"   // normal property access notation entity.age = 32 entity.save() entity.delete() datastore.withTransaction { // do stuff with your entities // within the transaction } 32 mercredi 20 octobre 2010
  • 38. Querying to be improved... import com.google.appengine.api.datastore.* der.* import static com.google.appengine.api.datastore.FetchOptions.Buil   // query the scripts stored in the datastore def query = new Query("savedscript")   // sort results by descending order of the creation date query.addSort("dateCreated", Query.SortDirection.DESCENDING)   author // filters the entities so as to return only scripts by a certain r) query.addFilter("author", Query.FilterOperator.EQUAL, params.autho   PreparedQuery preparedQuery = datastore.prepare(query)   // return only the first 10 results def entities = preparedQuery.asList( withLimit(10) ) 33 mercredi 20 octobre 2010
  • 39. ...into something groovier? def entities = datastore.query { select all from savedscript sort desc by dateCreated where author == params.author limit 10 } as List 34 mercredi 20 octobre 2010
  • 40. ...into something groovier? def entities = datastore.query { select all from savedscript sort desc by dateCreated where author == params.author limit 10 te d! } as List m en ple et Im o tY N 34 mercredi 20 octobre 2010
  • 41. Task queue API // access a configured queue using the subscript notation queues['dailyEmailQueue']   // or using the property access notation queues.dailyEmailQueue   // you can also access the default queue with: queues.default defaultQueue // add a task to the queue queue << [ countdownMillis: 1000, url: "/task/dailyEmail", taskName: "sendDailyEmailNewsletter", method: 'PUT', params: [date: '20090914'], payload: content ] 35 mercredi 20 octobre 2010
  • 42. Jabber / XMPP support (1/3) • Sending instant messages String recipient = "someone@gmail.com"   // check if the user is online if (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() } 36 mercredi 20 octobre 2010
  • 43. Jabber / XMPP support (2/3) • Sending instant messages with an XML payload String recipient = "service@gmail.com"   // check if the service is online if (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() } 37 mercredi 20 octobre 2010
  • 44. Jabber / XMPP support (2/3) • Sending instant messages with an XML payload String recipient = "service@gmail.com"   // check if the service is online if (xmpp.getPresence(recipient).isAvailable()) { // send the message def status = xmpp.send(to: recipient, xml: { customers { customer(id: 1) { <customers> name 'Google' <customer id=’1’> } <name>Google</name> } </customer> </customers> })   // checks the message was successfully delivered to the service assert status.isSuccessful() } 37 mercredi 20 octobre 2010
  • 45. Jabber / XMPP support (3/3) • Receving incoming instant messages – Configure the XmppServlet in web.xml – Add the inbound message service in appengine-web.xml // get the body of the message message.body // get the sender Jabber ID message.from // get the list of recipients Jabber IDs message.recipients   // if the message is an XML document instead of a raw string message if (message.isXml()) { // get the raw XML message.stanza // get a document parsed with XmlSlurper message.xml } 38 mercredi 20 octobre 2010
  • 46. Memcache service • Map notation access to the cache } class Country implements Serialzable { String name   def countryFr = new Country(name: 'France')   in the cache // use the subscript notation to put a country object // (you can also use non-string keys) memcache['FR'] = countryFr   // check that a key is present in the cache if ('FR' in memcache) { the cache using a key // use the subscript notation to get an entry from def countryFromCache = memcache['FR'] } 39 mercredi 20 octobre 2010
  • 47. Closure memoization • Cache the return values for each dinstinct invocation (for a given arguments set) -> def countEntities = memcache.memoize { String kind datastore.prepare( new Query(kind) ) .countEntities() } // first call def totalPics = countEntityes('photos') // second call, hitting the cache totalPics = countEntityes('photos') 40 mercredi 20 octobre 2010
  • 48. Blobstore enhancements • The blobstore allows to store some large content – images, videos, etc. def blob = ... print blob.filename // contentType, creation, size // output the content of the blob to the response blob.serve response // read the content of the blob blob.withReader { Reader r -> ... } blob.withStream { InputStream is -> ... } // delete the blob blob.delete() 41 mercredi 20 octobre 2010
  • 49. Images service • Readable DSL for manipulating images 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) 42 mercredi 20 octobre 2010
  • 50. Capabilities • Google App Engine allows you to know the status and availability of the various services – DATASTORE, DATESTORE_WRITE, MEMCACHE, etc. – ENABLED, DISABLED, UNKNOWN, SCHEDULED_MAINTENANCE – is() and not() methods if (capabilities[DATASTORE_WRITE].is(ENABLED)) { // write some content in the datastore } else { // otherwise, redirect to some maintenance page } 43 mercredi 20 octobre 2010
  • 51. URL Routing system (1/2) • You can have friendly URL mappings with the URL routing system all "/blog/@year/@month/@day/@title", @day@title=@title" forward: "/blog.groovy?year=@year&month=@month@day= get "/blog/@year/@month/@day", @day" forward: "/blog.groovy?year=@year&month=@month@day= all "/aboutus", redirect: "/blog/2008/10/20/about-us" get "/book/isbn/@isbn", forward: "/book.groovy?isbn=@isbn", validate: { isbn ==~ /d{9}(d|X)/ } 44 mercredi 20 octobre 2010
  • 52. URL Routing system (2/2) • Namespace awareness: nice for multitenancy • Capability awareness: for graceful degradation // @cust customer variable could be « acme » post "/@cust/update", forward: "/update.groovy", namespace: { "ns-$cust" } es status // different destinations depending on the GAE servic 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 } 45 mercredi 20 octobre 2010
  • 53. Simple plugin system (1/3) • Gaelyk 0.4 introduced 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 – provide any static content – add new libraries – do any initialization 46 mercredi 20 octobre 2010
  • 54. Simple plugin system (2/3) • 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 47 mercredi 20 octobre 2010
  • 55. Simple plugin system (3/3) • An example plugin descriptor – /WEB-INF/plugins/jsonPlugin.groovy import net.sf.json.* import net.sf.json.groovy.*   // add new variables in the binding binding { le jsonLibVersion = "2.3"          // a simple string variab  of a 3rd‐party JAR json = new JsonGroovyBuilder()  // an instance of a 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   // any other initialization code you'd need 48 mercredi 20 octobre 2010
  • 56. Summary SpringOne 2GX 2010. All rights reserved. Do not distribute without permission. mercredi 20 octobre 2010
  • 57. What’s coming next? • Gaelyk 0.5.5 released a week ago with additional URL routing support (capabilities, namespace) – and a 0.5.6 bug fix this past weekend • Expect more sugar around the Datastore • An SQL-like query DSL • Easier relationship management (builder) • Perhaps pre-compiled groovlets and templates • More generally... – Anything that’ll come up in upcoming GAE SDK versions 50 mercredi 20 octobre 2010
  • 58. 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 • Pretty cheap – You need a high-trafficed website to reach the quotas • Gaelyk provides a simplified approach to creating Servlet centric webapps in a productive manner – Leveraging Groovy’s servlet / template support and dynamic capabilities 51 mercredi 20 octobre 2010
  • 59. Q&A SpringOne 2GX 2010. All rights reserved. Do not distribute without permission. mercredi 20 octobre 2010
  • 60. Thanks for your attention! e e Laforg velopment Gu illaum oovy De m of Gr e@gmail.co Head laforg E mail: g glaforge @ T witter: • References: • http://gaelyk.appspot.com/ • http://groovy.codehaus.org/ • http://code.google.com/appengine/ 53 mercredi 20 octobre 2010
  • 61. Images used in this presentation Bandage http://image.made-in-china.com/2f0j00fIGaTPEYDQnB/Elastic-Crepe-Bandage-Gauze-.jpg RIP http://gipsydan.files.wordpress.com/2009/11/rip.jpg Puzzle: http://www.everystockphoto.com/photo.php?imageId=263521 Light bulb: https://newsline.llnl.gov/retooling/mar/03.28.08_images/lightBulb.png Clouds http://www.morguefile.com/archive/display/627059 http://www.morguefile.com/archive/display/625552 http://www.morguefile.com/archive/display/629785 Duke ok GAE http://weblogs.java.net/blog/felipegaucho/archive/ae_gwt_java.png Python logo : http://python.org/images/python-logo.gif Gaelyc cross with clouds : http://www.morguefile.com/archive/display/37889 Speed limit : http://www.morguefile.com/archive/display/18492 Warehouse : http://www.morguefile.com/archive/display/85628 Snow 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.jpg 54 mercredi 20 octobre 2010