SlideShare une entreprise Scribd logo
1  sur  71
Guill aume
 La forge




             a lightweight Groovy toolkit
              for Google App Engine
Guill aume
 La forge




             a lightweight Groovy toolkit
              for Google App Engine
Guillaume Laforge / @glaforge

• Groovy Project Manager
• Head of Groovy Development
  at SpringSource
• Initiator of the Grails framework
• Founder of the Gaelyk toolkit
• Co-author of Groovy in Action
• Member of «Les Cast Codeurs» podcast

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

                                                    2
Cloud
Computing
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
                                       4
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
                                       4
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
                                       4
Google App Engine

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

• Initially just Python supported

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


• Several JVM-compatible language supported


                                              5
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

                                                          6
Available services

• Memcache                       – Send / receive Jabber
                                   messages (GTalk)
  – JCache implementation
  – 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...

                                                               7
Limitations

•30 seconds request duration limit
  – Task queues raised to 10 minutes

• 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


                                               8
Quotas




         9
Quotas (1/2)

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



                                                   10
Quotas (2/2)

•XMPP                     •Memcache
 – 46M calls/day           – 8.6M calls/day
 – 1GB data sent/day       – 640GB in
 – 46M recepients/day      – 558GB out
 – 100K invitations/day
                          •Task queues
•Image manipulation        – 100K calls

 –864 calls/day
 –1GB in / 5GB out
 –2.5M transforms



                                              11
The Datastore
The datastore...

• 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


                                                   13
...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

                                                        14
Nice dashboard
http://gaelyk.appspot.com




                       F
http://gaelyk.appspot.com




                       F
• 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


                                                           17
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




                                                               18
19
19
19
19
19
19
19
19
19
19
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/
The web.xml

                                                                 ">
 <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5
   <listener>
                                                                  /servlet-class>
     <listener-class>groovyx.gaelyk.GaelykServletContextListener<
   </listener>
   <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>
  </web-app>




                                                                                    21
MVC: Groovlets and templates




      Groovlets                  Templates
     (controllers)                 (views)




                      Entities
                     (domain)
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
            }
        }




                                                       23
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
            }
                                                      di ng
                                                 oa
        }

                                            -rel
                                         to
                                     Au
                                                              23
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>


                                                  24
A template

      <html>
          <body>
               <p><%
                   def message = "Hello World!"
                   print message %>
               </p>
               <p><%= message %></p>
               <p>${message}</p>
               <ul>
               <% 3.times { %>
                    <li>${message}</li>
               <% } %>
                                                  di ng
               </ul>
                                            el oa
           </body>
                                       to -r
                                   Au
       </html>


                                                          24
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 /
  –xmpp                       redirect
  –namespace                 –println / print

                                                      25
D E M O
          26
Groovy sugar!
Sending emails with Gaelyk




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




                                          28
...compared to Java


Properties props = new Properties();
                                                    , null);
Sessio n session = Session.getDefaultInstance(props

try {
    Message msg = new MimeMessage(session);
                                                    om"));
    msg .setFrom(new InternetAddress("other@gmail.c
                                             O,
    msg.addRecipient(Message.RecipientType.T
                                            o@example.com"));
                     new InternetAddress("t
    msg.setSubject("Hello World");
    msg.setText("<bold>Hello</bold>");
    Transport.send(msg);
} catch (AddressException e) {}
} catch (MessagingException e) {}




                                                                29
Accessing the datastore

• Direct interaction with the low-level datastore API
         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()   // asyncSave()
         entity.delete() // asyncDelete()

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

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

                                                            30
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) )




                                                                              31
...into something groovier?



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




                                         32
...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
                                 p le
                           et Im
                       o tY
                     N


                                                  32
URL Routing system (1/4)

• You can have friendly URL mappings with the URL
  routing system
 all "/aboutus",
     redirect: "/blog/2008/10/20/about-us"

 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=

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


  – You’ll have to configure the RouteFilter in web.xml

                                                                              33
URL Routing system (2/4)

• You can also define caching times

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

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


  – Nice for GAE’s infamous «loading requests»
    •less critical with GAE SDK 1.4
      – ability to reserve 3 instances (billing)
      – warmup requests

                                                   34
URL Routing system (3/4)

• Special routes for specifying
  – incoming emails
  – jabber messages



         email to "/incomingMail.groovy"

          jabber to "/incomingXmpp.groovy"




                                             35
URL Routing system (4/4)

• 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
 }

                                                                   36
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


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



                                                        37
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
   ]


                                                               38
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()
   }



                                                           39
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()
   }



                                                                         40
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()
   }



                                                                            40
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 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
   }
                                                                          41
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']
 }




                                                                                42
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')



                                                           43
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()

                                                       44
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)


                                               45
Channel Service

• For Comet-style applications

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



• Then in the view, in JavaScript...

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




                                                     46
Simple plugin system (1/3)

• 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
                                                 47
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



                                                     48
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

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

  //
any
other
initialization
code
you'd
need

                                                                                      49
a ry
                                         m m
               S u




Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
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
What’s coming next?

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


• Perhaps pre-compiled groovlets and templates
  – Less needed since SDK 1.4
    • (reserve 3 hot instances, warmup requests)


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

• Anything that’ll come up in newer GAE SDK versions


                                                       52
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
Picture credits

 Myself http://www.flickr.com/photos/romainguy/783719255/sizes/l/in/photostream/
 Speed limit : http://www.morguefile.com/archive/display/18492
 Warehouse : http://www.morguefile.com/archive/display/85628
 Check mark: http://www.lnl.infn.it/~epics/WikiDumps/localhost/600px-symbol_ok.svg.png
 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
 Gaelic cross with clouds : http://www.morguefile.com/archive/display/37889
 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

Contenu connexe

Tendances

Language-Oriented Programming and Language Workbenches: Building Domain Langu...
Language-Oriented Programming and Language Workbenches: Building Domain Langu...Language-Oriented Programming and Language Workbenches: Building Domain Langu...
Language-Oriented Programming and Language Workbenches: Building Domain Langu...elliando dias
 
Eclipse Pdt2.0 26.05.2009
Eclipse Pdt2.0 26.05.2009Eclipse Pdt2.0 26.05.2009
Eclipse Pdt2.0 26.05.2009Bastian Feder
 
Quick Intro To JRuby
Quick Intro To JRubyQuick Intro To JRuby
Quick Intro To JRubyFrederic Jean
 
Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in RubyRoss Lawley
 
Ola Bini J Ruby Power On The Jvm
Ola Bini J Ruby Power On The JvmOla Bini J Ruby Power On The Jvm
Ola Bini J Ruby Power On The Jvmdeimos
 
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode ObjectsEWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode ObjectsRob Tweed
 
CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...
CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...
CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...Chris Richardson
 

Tendances (11)

Language-Oriented Programming and Language Workbenches: Building Domain Langu...
Language-Oriented Programming and Language Workbenches: Building Domain Langu...Language-Oriented Programming and Language Workbenches: Building Domain Langu...
Language-Oriented Programming and Language Workbenches: Building Domain Langu...
 
Intro to J Ruby
Intro to J RubyIntro to J Ruby
Intro to J Ruby
 
Eclipse Pdt2.0 26.05.2009
Eclipse Pdt2.0 26.05.2009Eclipse Pdt2.0 26.05.2009
Eclipse Pdt2.0 26.05.2009
 
OSLC-CM connector in SD
OSLC-CM connector in SDOSLC-CM connector in SD
OSLC-CM connector in SD
 
Webcast Net-OSLC-CM
Webcast Net-OSLC-CMWebcast Net-OSLC-CM
Webcast Net-OSLC-CM
 
Quick Intro To JRuby
Quick Intro To JRubyQuick Intro To JRuby
Quick Intro To JRuby
 
Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in Ruby
 
Ola Bini J Ruby Power On The Jvm
Ola Bini J Ruby Power On The JvmOla Bini J Ruby Power On The Jvm
Ola Bini J Ruby Power On The Jvm
 
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode ObjectsEWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
EWD 3 Training Course Part 22: Traversing Documents using DocumentNode Objects
 
CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...
CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...
CommunityOneEast 09 - Dynamic Languages: the next big thing for the JVM or an...
 
JSX
JSXJSX
JSX
 

Similaire à Gaelyk - JFokus 2011 - Guillaume 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
 
Google App Engine Java, Groovy and Gaelyk
Google App Engine Java, Groovy and GaelykGoogle App Engine Java, Groovy and Gaelyk
Google App Engine Java, Groovy and GaelykGuillaume Laforge
 
DrupalCampLA 2014 - Drupal backend performance and scalability
DrupalCampLA 2014 - Drupal backend performance and scalabilityDrupalCampLA 2014 - Drupal backend performance and scalability
DrupalCampLA 2014 - Drupal backend performance and scalabilitycherryhillco
 
Google Cloud Platform, Compute Engine, and App Engine
Google Cloud Platform, Compute Engine, and App EngineGoogle Cloud Platform, Compute Engine, and App Engine
Google Cloud Platform, Compute Engine, and App EngineCsaba Toth
 
Servletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postServletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postvamsitricks
 
Servletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postServletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postvamsi krishna
 
Rapid Application Development on Google App Engine for Java
Rapid Application Development on Google App Engine for JavaRapid Application Development on Google App Engine for Java
Rapid Application Development on Google App Engine for JavaKunal Dabir
 
Servletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postServletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postvamsitricks
 
Code for Startup MVP (Ruby on Rails) Session 1
Code for Startup MVP (Ruby on Rails) Session 1Code for Startup MVP (Ruby on Rails) Session 1
Code for Startup MVP (Ruby on Rails) Session 1Henry S
 
Web Development using Ruby on Rails
Web Development using Ruby on RailsWeb Development using Ruby on Rails
Web Development using Ruby on RailsAvi Kedar
 
Appscale at CLOUDCOMP '09
Appscale at CLOUDCOMP '09Appscale at CLOUDCOMP '09
Appscale at CLOUDCOMP '09Chris Bunch
 
Cloud Platforms for Java
Cloud Platforms for JavaCloud Platforms for Java
Cloud Platforms for Java3Pillar Global
 
Servlet and JSP
Servlet and JSPServlet and JSP
Servlet and JSPGary Yeh
 
AWS (Hadoop) Meetup 30.04.09
AWS (Hadoop) Meetup 30.04.09AWS (Hadoop) Meetup 30.04.09
AWS (Hadoop) Meetup 30.04.09Chris Purrington
 
Cannibalising The Google App Engine
Cannibalising The  Google  App  EngineCannibalising The  Google  App  Engine
Cannibalising The Google App Enginecatherinewall
 
Week 05 Web, App and Javascript_Brandon, S.H. Wu
Week 05 Web, App and Javascript_Brandon, S.H. WuWeek 05 Web, App and Javascript_Brandon, S.H. Wu
Week 05 Web, App and Javascript_Brandon, S.H. WuAppUniverz Org
 
Introduction to Jquery
Introduction to JqueryIntroduction to Jquery
Introduction to JqueryGurpreet singh
 
“Purikura” culture in Japan and our web application architecture
“Purikura” culturein Japan andour web application architecture“Purikura” culturein Japan andour web application architecture
“Purikura” culture in Japan and our web application architectureKoichi Sakata
 
Pure Speed Drupal 4 Gov talk
Pure Speed Drupal 4 Gov talkPure Speed Drupal 4 Gov talk
Pure Speed Drupal 4 Gov talkBryan Ollendyke
 

Similaire à Gaelyk - JFokus 2011 - Guillaume Laforge (20)

Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
 
Google App Engine Java, Groovy and Gaelyk
Google App Engine Java, Groovy and GaelykGoogle App Engine Java, Groovy and Gaelyk
Google App Engine Java, Groovy and Gaelyk
 
DrupalCampLA 2014 - Drupal backend performance and scalability
DrupalCampLA 2014 - Drupal backend performance and scalabilityDrupalCampLA 2014 - Drupal backend performance and scalability
DrupalCampLA 2014 - Drupal backend performance and scalability
 
Google Cloud Platform, Compute Engine, and App Engine
Google Cloud Platform, Compute Engine, and App EngineGoogle Cloud Platform, Compute Engine, and App Engine
Google Cloud Platform, Compute Engine, and App Engine
 
Servletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postServletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,post
 
Servletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postServletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,post
 
Rapid Application Development on Google App Engine for Java
Rapid Application Development on Google App Engine for JavaRapid Application Development on Google App Engine for Java
Rapid Application Development on Google App Engine for Java
 
Servletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,postServletarchitecture,lifecycle,get,post
Servletarchitecture,lifecycle,get,post
 
Code for Startup MVP (Ruby on Rails) Session 1
Code for Startup MVP (Ruby on Rails) Session 1Code for Startup MVP (Ruby on Rails) Session 1
Code for Startup MVP (Ruby on Rails) Session 1
 
Web Development using Ruby on Rails
Web Development using Ruby on RailsWeb Development using Ruby on Rails
Web Development using Ruby on Rails
 
Appscale at CLOUDCOMP '09
Appscale at CLOUDCOMP '09Appscale at CLOUDCOMP '09
Appscale at CLOUDCOMP '09
 
Cloud Platforms for Java
Cloud Platforms for JavaCloud Platforms for Java
Cloud Platforms for Java
 
Servlet and JSP
Servlet and JSPServlet and JSP
Servlet and JSP
 
AWS (Hadoop) Meetup 30.04.09
AWS (Hadoop) Meetup 30.04.09AWS (Hadoop) Meetup 30.04.09
AWS (Hadoop) Meetup 30.04.09
 
Supa fast Ruby + Rails
Supa fast Ruby + RailsSupa fast Ruby + Rails
Supa fast Ruby + Rails
 
Cannibalising The Google App Engine
Cannibalising The  Google  App  EngineCannibalising The  Google  App  Engine
Cannibalising The Google App Engine
 
Week 05 Web, App and Javascript_Brandon, S.H. Wu
Week 05 Web, App and Javascript_Brandon, S.H. WuWeek 05 Web, App and Javascript_Brandon, S.H. Wu
Week 05 Web, App and Javascript_Brandon, S.H. Wu
 
Introduction to Jquery
Introduction to JqueryIntroduction to Jquery
Introduction to Jquery
 
“Purikura” culture in Japan and our web application architecture
“Purikura” culturein Japan andour web application architecture“Purikura” culturein Japan andour web application architecture
“Purikura” culture in Japan and our web application architecture
 
Pure Speed Drupal 4 Gov talk
Pure Speed Drupal 4 Gov talkPure Speed Drupal 4 Gov talk
Pure Speed Drupal 4 Gov talk
 

Plus de Guillaume 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
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 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
 
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 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
 
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
 

Plus de Guillaume Laforge (20)

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
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 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
 
Groovy 2 and beyond
Groovy 2 and beyondGroovy 2 and beyond
Groovy 2 and beyond
 
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 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
 
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
 

Dernier

Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 

Dernier (20)

Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 

Gaelyk - JFokus 2011 - Guillaume Laforge

  • 1. Guill aume La forge a lightweight Groovy toolkit for Google App Engine
  • 2. Guill aume La forge a lightweight Groovy toolkit for Google App Engine
  • 3. Guillaume Laforge / @glaforge • Groovy Project Manager • Head of Groovy Development at SpringSource • Initiator of the Grails framework • Founder of the Gaelyk toolkit • Co-author of Groovy in Action • Member of «Les Cast Codeurs» podcast • Speaker: JavaOne, QCon, JavaZone, Sun TechDays, Devoxx, The Spring Experience, SpringOne2GX, JAX, Dynamic Language World, IJTC, and more... 2
  • 5. 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 4
  • 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 4
  • 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 4
  • 8. Google App Engine • Google’s PaaS solution • Run your app on Google’s infrastructure • Initially just Python supported • Java supported added too – Sandboxed JVM – Jetty servlet container • Several JVM-compatible language supported 5
  • 9. 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 6
  • 10. Available services • Memcache – Send / receive Jabber messages (GTalk) – JCache implementation – 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... 7
  • 11. Limitations •30 seconds request duration limit – Task queues raised to 10 minutes • 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 8
  • 12. Quotas 9
  • 13. Quotas (1/2) •Bandwidth •Mail – 43.2M requests/day – 7K calls/day – 1GB/day in/out – 2K recepients/day – 6.5 CPU hours/day – 5K emails/day – 2K attachments – 100MB of attachments •Datastore – 10M calls – 1GB/day •URL Fetch – 12GB in / 115GB out – 657K calls/day – 60 CPU hours/day – 4GB in/out /day 10
  • 14. Quotas (2/2) •XMPP •Memcache – 46M calls/day – 8.6M calls/day – 1GB data sent/day – 640GB in – 46M recepients/day – 558GB out – 100K invitations/day •Task queues •Image manipulation – 100K calls –864 calls/day –1GB in / 5GB out –2.5M transforms 11
  • 16. The datastore... • 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 13
  • 17. ...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 14
  • 21. • 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 17
  • 22. 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 18
  • 23. 19
  • 24. 19
  • 25. 19
  • 26. 19
  • 27. 19
  • 28. 19
  • 29. 19
  • 30. 19
  • 31. 19
  • 32. 19
  • 33. 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/
  • 34. The web.xml "> <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5 <listener> /servlet-class> <listener-class>groovyx.gaelyk.GaelykServletContextListener< </listener> <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> </web-app> 21
  • 35. MVC: Groovlets and templates Groovlets Templates (controllers) (views) Entities (domain)
  • 36. 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 } } 23
  • 37. 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 } di ng oa } -rel to Au 23
  • 38. 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> 24
  • 39. A template <html> <body> <p><% def message = "Hello World!" print message %> </p> <p><%= message %></p> <p>${message}</p> <ul> <% 3.times { %> <li>${message}</li> <% } %> di ng </ul> el oa </body> to -r Au </html> 24
  • 40. 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 / –xmpp redirect –namespace –println / print 25
  • 41. D E M O 26
  • 43. Sending emails with Gaelyk mail.send to: 'to@gmail.com', from: 'other@gmail.com', subject: 'Hello World', htmlBody: '<bold>Hello</bold>' 28
  • 44. ...compared to Java Properties props = new Properties(); , null); Sessio n session = Session.getDefaultInstance(props try { Message msg = new MimeMessage(session); om"));     msg .setFrom(new InternetAddress("other@gmail.c O,     msg.addRecipient(Message.RecipientType.T o@example.com"));                      new InternetAddress("t     msg.setSubject("Hello World");     msg.setText("<bold>Hello</bold>");     Transport.send(msg); } catch (AddressException e) {} } catch (MessagingException e) {} 29
  • 45. Accessing the datastore • Direct interaction with the low-level datastore API 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() // asyncSave() entity.delete() // asyncDelete() datastore.withTransaction { // do stuff with your entities // within the transaction } // use the asynchronous datastore service datastore.async.put(entity) 30
  • 46. 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) ) 31
  • 47. ...into something groovier? def entities = datastore.query { select all from savedscript sort desc by dateCreated where author == params.author limit 10 } as List 32
  • 48. ...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 p le et Im o tY N 32
  • 49. URL Routing system (1/4) • You can have friendly URL mappings with the URL routing system all "/aboutus", redirect: "/blog/2008/10/20/about-us" 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= get "/book/isbn/@isbn", forward: "/book.groovy?isbn=@isbn", validate: { isbn ==~ /d{9}(d|X)/ } – You’ll have to configure the RouteFilter in web.xml 33
  • 50. URL Routing system (2/4) • You can also define caching times get "/aboutus", cache: 24.hours, forward: "/aboutus.gtpl" get "/breaking-news", cache: 1.minute, forward: "/news.groovy?last=10" – Nice for GAE’s infamous «loading requests» •less critical with GAE SDK 1.4 – ability to reserve 3 instances (billing) – warmup requests 34
  • 51. URL Routing system (3/4) • Special routes for specifying – incoming emails – jabber messages email to "/incomingMail.groovy" jabber to "/incomingXmpp.groovy" 35
  • 52. URL Routing system (4/4) • 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 } 36
  • 53. 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 if (capabilities[DATASTORE_WRITE].is(ENABLED)) { // write some content in the datastore } else { // otherwise, redirect to some maintenance page } 37
  • 54. 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 ] 38
  • 55. 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() } 39
  • 56. 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() } 40
  • 57. 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() } 40
  • 58. 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 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 } 41
  • 59. 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'] } 42
  • 60. 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') 43
  • 61. 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() 44
  • 62. 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) 45
  • 63. Channel Service • For Comet-style applications def token = channel.createChannel('clientID') channel.send 'clientID', 'Hi!' • Then in the view, in JavaScript... channel = new goog.appengine.Channel(token); socket = channel.open(); socket.onmessage = function(msg) { ... } 46
  • 64. Simple plugin system (1/3) • 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 47
  • 65. 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 48
  • 66. 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 before
{
req,
resp
‐>
...
}
//
or
after 
 //
any
other
initialization
code
you'd
need 49
  • 67. a ry m m S u Copyright 2011 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
  • 68. 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
  • 69. What’s coming next? • Expect more sugar around the Datastore – An SQL-like query DSL – Easier relationship management (builder?) • Perhaps pre-compiled groovlets and templates – Less needed since SDK 1.4 • (reserve 3 hot instances, warmup requests) • Testing facilities specific to Gaelyk –testing utility class, Spock-specific ones... • Anything that’ll come up in newer GAE SDK versions 52
  • 70. 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
  • 71. Picture credits Myself http://www.flickr.com/photos/romainguy/783719255/sizes/l/in/photostream/ Speed limit : http://www.morguefile.com/archive/display/18492 Warehouse : http://www.morguefile.com/archive/display/85628 Check mark: http://www.lnl.infn.it/~epics/WikiDumps/localhost/600px-symbol_ok.svg.png 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 Gaelic cross with clouds : http://www.morguefile.com/archive/display/37889 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

Notes de l'éditeur

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n