Gaining Visibility Into Enterprise Spring Applications with tc ServerSpring Edition #s2gx

Gaining Visibility Into Enterprise Spring Applications with tc Server Spring EditionSteve Mayzak – SpringSource

  • tc Server — enterprise version of Tomcat developed by SpringSource
  • Built on Tomcat
  • Survey in 2008: 68% of companies surveyed using Tomcat; most popular lightweight container

tc Server editions

  • developer edition — can get it when you download STS
  • standard edition — application provisioning, server administration, advanced diagnostics
  • spring edition — spring + tomcat stack, spring application visibility, spring performance management

tc Server: Key Highlights

  • Developer efficiency
  • operational control
  • deployment flexibility

Spring Insight

  • Spring Insight — knows about Spring and Grails applications, so can provide specific information about your apps as they’re running
  • When you deploy a WAR to tc Server, Spring Insight gets involved and get get specific information from your apps
  • Spring Insight is currently intended for development use only
  • DEMO: huge amount of details come out of Spring Insight, from the HTTP request details down to the JDBC statements that were run and timings on the various actions during the request
  • can use Insight with other frameworks, etc. as well by adding annotations to your code

Operational Control

  • performance & sla management of spring apps
  • application provisioning and server administration
  • rich alert definition, workflows, and control actions
  • group availability & event dashboards
  • secure unidirectional agent communications
  • tc Server is a combination of Hyperic and Tomcat
  • monitoring is done via valves in Tomcat–isn’t a fork or modified version of Tomcat
  • Hyperic monitors web servers, app servers, databases, caching, messaging, directories, virtualization, etc.
  • Hyperic is also a management tool–admin, provisioning, groups, metrics, alerts, events, access control, upgrades, etc.
    • hyperic is jmx based, runs as an agent on each server

Enterprise Capabilities in tc Server

  • Run multiple instances per install — creates tc Server install updates
    • tc Server instances can point to a central set of binaries so upgrades are simpler
  • advanced scalability options
    • non-blocking (NIO) conectors
    • high-concurrency connection pool
  • Can create tc Server templates and create multiple instances from a base template
  • Advanced diagnostics–detects deadlocks and slow-running requests

Hyperic

  • monitoring and deployment
  • can see what apps are running on tc Server, number of sessions on the apps, up/down times, etc.
  • can deploy war files and change context path as you deploy
  • can schedule deployments and have the server auto-restart
  • can deploy from a remote machine (e.g. build server)
  • can remotely stop/start/restart instances
  • can set up scheduled restarts–e.g. make configuration changes during the day, have server auto-restart after hours
  • can schedule recurring restarts (e.g. restart daily at 1 am)
  • hyperic consumes jmx metrics and can show them in context, meaning it shows application metrics in the context of the overall server health (cpu, memory, etc.)
  • with the metrics coming in you can look at the specifics of your application and tune according to what your specific application is doing
    • has everything from cpu, memory, disk I/O metrics, to request metrics, down to spring-specific metrics
  • can add JMX instrumentation to your own classes without having to write your own MBeans–just annotate with @ManagedResource, @ManagedMetric, @ManagedOperation, @ManagedAttribute
    • this lets you get down to questions like “how many bookings per second can I handle in my travel booking application?” which lets you plan infrastructure and scalability in a very granular way
  • hyperic does metric baselining for your specific app so you’ll get alerts based on the baseline metrics for your application
  • can enable/disable metrics and alerts across multiple servers from a single interface
  • can see metrics globally (across a cluster) or individually on each server

Deployment Flexibility

  • Lean server (10MB) for virtual environments
  • template-drive server instance creation
  • integrated experience with vmware environments
  • open, secure API for all operations
  • server-specific settings like ports, etc. have been taken out and put into a catalina properties file, so server.xml can be applicable to all servers
  • streamlines process of spinning up new server instances
  • shared binaries for upgrades
  • multiple server versions can be installed per machine
  • complete flexibility for various “sizes” of VMs

Session Notes – Grails Without a Browser

Presenter: Jeff Brown, SpringSource

  • grails typically thought of as a web framework (which it is), but there are significant applications built with grails that have no browser front-end at all
  • interesting work done at LinkedIn in this regard
    • talked about it in public at JavaOne last year
    • primary revenue generating app is a grails app (partner interaction, etc.)
      • this app has no browser front-end to it
      • built a business/service layer all in grails
      • have other applications that sit in front of this that aren’t grails
  • lots of stuff in grails doesn’t have anything to do with building web apps specifically
    • GORM
    • service layer
    • these make good sense in any application
  • can think of grails as a platform–similar to eclipse platform
    • eclipse IDE is what you think of, but the IDE is really just one app on top of the eclipse platform
    • e.g. substantial parts of grails are being used in griffon for building desktop apps
  • grails 0.4 was the first release that had the plugin system in it
    • interview soon after this release–jeff was asked what was coming up in the following year
    • hope was that they’d see a lot of development in the plugin space
    • turned out that there’s a far more active and productive plugin community than they had hoped
    • shows the power of the plugin architecture in grails as well as grails as a platform in general
  • some plugins have nothing to do with an html ui
    • remoting plugins
      • exposes services to remote calls
      • can have the grails side interacting with GORM as per usual, but make these services available to RMI, SOAP, etc.
    • good REST support built right into the framework

Code Demo

  • simple app with Car domain class, CarService
  • services
    • transactional by default
    • instance of service class is automatically added to the spring application context
  • installing xfire SOAP plugin
    • inside a service can declare a property using “expose”, e.g. static expose = [‘xfire’] in the service
      • this will inspect services that have an expose property declared and make them available via xfire
    • also plugins for exposing as rmi, jms, etc.
  • after fire the app up can browse to http://localhost:8080/context/services to see a list of service WSDLs
    • xfire generated the wsdl automatically
    • can test with something like SOAP UI–UI tool to allow you to exercise web services
  • as you define other operations within the service, the WSDL gets regenerated as needed to expose the new methods
    • with xfire you do need to bounce the app for it to pick up the changes
  • creating a groovy script as a command-line client to the exposed service
    • create a groovyx.net.ws.WSClient, give it the URL to the WSDL, and can then call methods on the web service
    • WSClient is an external project (not core to groovy) so you do need to add it to your classpath
  • note that you don’t have access to the Car class when you get back data from the web service
    • you aren’t getting back serialized Car objects, it’s returning WSClient type of ArrayOfWhatever
      • basically you get back a list of arrays–each array contains the property of the Car object
        • really JAXB elements that contain an xml representation of the car
  • note that by default all of your services are singletons (stateless)
    • if you do happen to have a service that DOES have state, need to worry about thread safety
      • can specify that the bean is scoped in any one of the valid spring scopes
  • controllers are not singletons since they have state–new controllers are created for every request
  • xfire may or may not support (need to check) not exposing specific methods within a service using something like webparam annotations
  • installing jmx plugin
    • can add another entry to the expose property, e.g. static expose = [‘xfire’, ‘jmx’]
      • still exposed as SOAP, but also available to jmx
  • creating simple math service
  • can create a griffon client to access the grails service
  • demoing creation of griffon app (results in a swing app)
    • showing two text input fields in swing app, click button to make call to grails service to add the two numbers together
    • actually clicking on the button calls a griffon controller, and the griffon controller makes the web service call to the grails service
      • creating an instance of groovy’s WSClient in the griffon controller and calling the same way as from the command line client
  • now creating a RESTful interface to the math service
    • adding a MathController to the grails app with a “product” action to multiply two numbers
    • return from the controller is xml
    • showing calling this in the browser but of course this could be called from anything that can accept xml as the return format
  • now adding another component to the griffon application to do multiplication by calling the REST URL in the grails app
    • plugin for griffon to enable REST support
    • wind up with two buttons in the griffon app, one that makes a soap call, the other making a rest call
  • can use UrlMappings in a grails app to make things more RESTful
  • in controller you can specify the allowed HTTP request types that can be made to the controller by action, e.g. static allowedMethods = [delete:’POST’] would throw a 405 if any request type other than POST is made to the delete action
    • should never do anything destructive in response to a get request
    • if you write controllers from scratch the allowedMethods property is NOT there, and in most cases you’ll want to add it
  • in RESTful services, the request will come to the controller since controllers in grails apps are what respond to requests
    • can put logic in services to get it out of your controller, but the REST response since it’s based on HTTP request/response needs to be handled in the controller
    • controllers don’t have to render a *view* specifically, they just have to provide a response
      • response can be html, xml, json, etc.
  • when you think about grails, building web apps is a huge part of what it’s used for, but grails also handles “no browser” apps or multiple UI clients quite well
  • in the end your application is just responding to requests

Q&A

  • anyone working on a plugin so you can write an app that can render either a grails or griffon app?
    • nothing really going on in this specific area, but moving towards compatibility with grails and griffon plugins
    • in many cases you can do a search/replace on a grails plugin to replace “grails” with “griffon” and it’ll work in griffon
  • has linkedin experienced any scalability issues?
    • linkedin app get hits really hard and is holding up very well
    • being on the jvm means you have great existing solutions for deployment, scalability, monitoring, etc.
      • can do things in other frameworks (e.g. rails, django) perhaps as quickly as with grails, but that’s only one piece of the puzzle
  • what happens when an app and a plugin rely on different versions of the same jars?
    • no good solution for this at this point
    • after grails 1.2 is released, significant effort will be put into the plugin system–need to figure out what role OSGi will play in the future of grails
      • will grails apps and/or plugins turn into OSGi bundles? probably ponder this early next year
  • is GORM usable outside of Grails?
    • yes, and isn’t difficult to do now
    • wiring between gorm and the rest of grails is pretty decoupled at this point
    • can use GORM in griffon, for example–drop the GORM jar in and annotate classes, and everything works
      • all the gorm dependencies are in 1 JAR now
    • when using GORM outside of grails you do need to create your own boostrapper or use annotations so GORM knows about your domain model
  • error handling with soap?
    • inside controller action if you get bad data you can render the soap response with the error
    • grails doesn’t complicate or simplify any error handling with soap
    • anything you can do to specify timeouts, etc.?
      • rest client for griffon no, wsclient probably does
    • shouldn’t assume when something goes wrong in groovy/grails that you always get an exception
      • in many cases grails fails silently, e.g. if you call save() and it fails, it doesn’t throw an exception it just returns null
      • can now specify that save() throws an error if save fails
  • what about security with xfire and securing services?
    • can secure access to the webapp at the http level
    • don’t know if xfire plugin has specific user/role based access
    • controllers in REST would hook into everything that grails already does–just an http request to the webapp

Session Notes – Not Your Father’s Custom Tags

Presenter: Dave Klein

Custom Tags are Valuable

  • build reusable components
  • keep code out of pages
  • make pages more readable
    • even putting presentation/html code into custom tags can make the page more readable
  • encapsulate domain knowledge
    • easy for page designers to use without knowing much about the domain model, etc.

JSP Custom Tags are Painful

  • create handler class for each tag
  • implement one of several interfaces
  • implement interface’s methods
  • <pure_evil>define a TLD</pure_evil>
  • add a page directive for each TLD
  • great once they exist, but because they’re a pain to create people avoid them and don’t get the benefit
  • JSP custom tag for hello wolrd is 2+ pages of code, equivalent GSP tag is about 6 lines

The Power of JSP Without the Pain

  • convention over configuration
  • no tld, no xml
  • no interfaces to implement
  • a TagLibrary is a single groovy class
    • can contain multiple tags within this class
  • each tag is a closure
  • don’t need to declare within the page
    • if it’s in the project, it’s available on every page

GSP: A Quick-Start Guide

What you can do in a GSP tag

  • accept and use attributes
  • accept and conditionally use a body
  • access your domain model including all the GORM methods
  • call service classes
  • call other tags
    • other tags are called as methods from within a tag
  • access the session, request, and response

Implicit Objects in a GSP Tag

  • session (GrailsHttpSession)
  • request (HttpRequest)
  • response (GrailsContentBufferngResponse)
  • out (GSPResponseWriter)

Example Tag — Output Groovy Group List

  • def groupLinks = {
    def groups = GroovyGroup.list()
    out << “<br/><ul>”
    groups.each { group ->
    out << “<li><a href='”
    out << createLink(action:’show’, id:group.id)
    out << “‘>${group}”
    out << “</a></li>”
    }
    out << “</ul>
    }
  • call tag as <g:groupLinks />

Example Tag With a Body

  • def ifLoggedIn = { attrs, body ->
    def user = session.use
    if (user)
    out << body()
    }
  • <g:ifLoggedIn>
    info for logged in users goes here
    </g:ifLoggedIn>
  • note that in the tag code, the first parameter will be treated as a map of attrs so even if you’re not using attrs, but you’re using the body, still need to have a dummy parameter for attrs in order for things to work correctly

Using Custom Tags Instead of <g:if>

  • def buttonBar = {
    def user = session.user
    out << “<div class=’buttons’>”
    if (user) {
    // output buttons for logged in users here
    if (user.isAdmin()) {
    // output admin buttons here
    }
    } else {
    out << “<input type=’button’ value=’Login’ />”
    }
    out << “</div>”
    }
  • call tag as <g:buttonBar />

Testing Tags

  • very easy
  • tags when called as methods return a string
  • TagLibUnitTestCase makes it even easier
    • includes mocks for
      • session
      • request
      • response
  • includes other mocks from GrailsUnitTestCase

A Sample Test Class

  • import grails.test.*
    class DemoTagLibTests extends TagLibUnitTestCase {

    public void setUp() {
    super.setUp()
    tagLib.metaClass.createLink = { params ->
    /groovyGroups/show/${params.id}”
    } // Had to add this because otherwise createLink wouldn’t be available in the test
    // This would also be true of custom tags that aren’t in the same tag library
    }

    void testButtonBarWithAdmin() {
    mockSession.user = [isAdmin:{-> true}] // map is serving as mock object
    def output = tagLib.buttonBar() // tag itself is a closure, so can call as a method here
    assert output.toString().contains(‘Create Stuff’)
    }

    void testIfLoggedIn() {
    mockSession.user = “Anything can go here” // doesn’t matter what goes here since we’re just checking session.user
    def output = tagLib.ifLoggedIn([:]) {
    ‘User is logged in’
    }
    assertEquals output.toString(), ‘User is logged in’
    }

    void testGroupLinks() {
    mockDomain(GroovyGroup, // new GroovyGroup objects here …)
    def output = tagLib.groupLinks()
    assert output = tagLib.groupLinks()
    assert output.toString().contains(‘<a href=’)
    assert output.toString().contains(‘Group2’)
    }
    }

  • remember that unit tests run much faster but don’t have everything available, so if you find yourself mocking a ton of stuff in unit tests, that’s a good indication you need integration tests

Namespaces

  • if you don’t declare a namespace, uses g
  • put static namespace = ‘demo’ at the top of your taglib class to declare a namespace
  • use the namespace as a prefix when calling the tag as a method, e.g. namespace.tag()

Distributing TagLibs With Plugins

  • create a plugin project
  • create or copy a TagLib to the /taglib directory
  • package your plugin
  • Install your plugin in another application
  • your custom tags are now available in the application

Demo

  • showing demo of simple custom tag to replace a lot of the redundant stuff in the grails scaffolding
  • one limitation of gsp tags is you can’t have nested tags
    • you can fake this out a bit by leveraging the request scope
  • great use of gsp tags is to bundle up html, css, and javascript that gets output to the page
  • FieldData plugin available that does a lot of these sorts of things
  • check out the custom tags available in the grails core for good examples of how to do things

Session Notes – Grails Plugin System Part 2

Presenter: Graeme Rocher

Technical Plugins

  • typically a bit more complicated to implement
  • can mix and match technical and functional plugins
  • provide programming apis

Key Concepts

  • plugin lifecycle
  • GrailsApplication object
    • encapsulates the conventions in a project
  • Spring BeanBuilder
    • runtime spring configuration–need to understand the spring dsl
  • Metaprogramming

Plugin Lifecycle Hooks

  • enclosures that allow you to manipulate the grails runtime
  • def doWithWebDescriptor = { xml -> }
    • useful for creating plugin that manipulates web.xml
  • def doWithSpring = {}
    • can use full power of spring within a grails plugin
    • written in groovy so have full access to groovy in configuring spring
  • def doWithDynamicMethods = { applicationContext -> }
    • metaprogramming
    • e.g. could add a method that interacts with hibernate
    • since you have access to the applicationContext you have access to more or less everything
  • def doWithApplicationContext = { applicationContext -> }
    • post-processing

doWithWebDescriptor

  • programmatic modification of generated web.xml
  • useful for integrating third-party servlets/filters
  • groovy markupbuilder style dsl
    • easy to append to existing nodes in xml
  • automates a lot of configuration you’d otherwise have to do by hand
  • doesn’t happen during war deployment

doWithSpring

  • programmatically modify Spring ApplicationContext
  • groovy dsl that generates spring xml

doWithDynamicMethods

  • exercise your groovy metaprogramming skills
  • add new methods and properties to existing types
  • “delegate” is equivalent to “it” in metaprogramming
  • in java terms a lot of what you have to do is DI, etc. and your code becomes rather cluttered
    • e.g. in GORM there’s no reference to the fact that you’re using Hibernate in your domain classes
    • specific references are abstracted away

Additional Hooks

  • onChange
    • can re-add a method to a class when it changes
    • e.g. specify def observe = [‘plugins’] to watch for changes
  • onConfigChange

Plugin Life-Cycle Illustrated

  • grails loads first
  • loadPlugins() called next — pluginmanager created
  • following this, the plugin lifecycle points are called
  • all plugins, core and otherwise, are loaded at the same time
    • can specify with your own plugins if they should load explicitly before or after core plugins

Programming by Convention

  • every grails project has a set of conventions
  • configuration can be automated through conventions
  • grails supplies an API to inspect conventions via some key interfaces
    • GrailsApplication
    • GrailsClass

The GrailsApplication Interface

  • used for programming by convention
  • not an interface in the fixed Java term; dynamic object
  • inspect GrailsClass instances
  • extensible to new artefact types
  • available as a variable called application in plugins
  • interesting methods
    • Class[] getAllClasses() // gets all loaded classes
    • GrailsClass get*Class(String name) // gets a class by name
    • boolean is*Class(Class c) // checks if a class is of a given type
    • GrailsClass[] get*Classes() // all grailsclass instances of type
    • void add*Class(Class c)
    • all the * stuff in these examples are where you substitute the grails class type, e.g. getControllerClass(“fully.qualified.class.Name”)
  • can add new artefact handlers to add completely new artefact types to grails
    • can tell grails what the conventions are, e.g. “ends with X” or “lives in this directory”

Artefact Types

  • built in types
    • DomainClass
    • Controller
    • TagLib
    • Service
  • extensible to new by implementing ArtefactHandler

The GrailsClass Interface

  • allows you to further analyze conventions for each class
  • contains methods to get various forms of the class name
    • getShortName(): UserController (no package)
    • getPropertyName(): userController (bean name)
    • getNaturalName(): User Controller
    • others …
      • getLogicalPropertyName(), getPackageName(), etc.

Demo: Building a Technical Plugin

  • building an API to twitter
  • using twitter4j — twitter api for java
    • drop jar in lib directory of project
  • create a new public twitter bean in the doWithSpring plugin point
    • default constructor assumes public timeline
  • in doWithDynamicMethods are going to add ability for spring security users to submit to twitter
    • adding dynamic tweet() method to string class
    • String.metaclass.tweet = { ->
      def auth = SecurityContextHolder.context?.authentication
      if (auth instanceOf UsernamePasswordAuthenticationToken) {
      def twitter = new Twitter(auth.principal, auth.credentials)
      twitter.updateStatus(delegate)
      } else {
      throw new TwitterException(“user not logged in”)
      }
      }

Convention-Based Programming

  • have classes in the system, want to mark these as a “tweeter”
  • want to be able to call twitter methods to a user who’s marked as a tweeter
  • implement this in doWithDynamicMethods
  • inside each hook there is an implicit application keyword that represents the application context
    • application.domainClasses.each { GrailsDomainClass dc ->
      def metaClass = dc.metaClass
      metaClass.tweet = { String message ->
      def twitter = new Twitter(delegate.username, delegate.password)
      twitter.updateStatus(message)
      }

      metaClass.getLatestTweets = { ->
      def twitter = new Twitter(delegate.username, delegate.password)
      twitter.getPublicTimeline().text // property doesn’t exist but gpath automatically grabs text property of each object
      }
      }

Summary

  • more advanced knowledge of the grails plugin system opens up a world of possibilities
  • combine technical and functional plugins to enable new levels of productivity
  • harness the power of groovy metaprogramming!
  • helps avoid reinvention and duplication across applications

Q&A

  • inside any plugin you can do grails create-script and specify a gant script
    • used to extend the grails command line interface
  • plugins can provide different scaffolding templates to override the default ones and create your own uis
  • “plugins are the most important thing about grails”
  • any thoughts about how to eliminate bad/abandoned plugins from the central repository?
    • hudson build of all tests on all plugins done by a user
    • thoughts of integrating this into grails.org to give plugins a health status
  • plans to move plugins into git instead of SVN?
    • in grails 1.2 you can export plugin as a zip only so you can manage your source in git but still deploy to svn
    • complete move to git might be considered further down the line
  • SpringSource officially supports specific plugins

Session Notes – Grails Plugin System Part 1

Presenter: Graeme Rocher

Agenda

  • plugin quick start
  • technical vs. functional plugins
  • plugins for modularity
  • distribution and dependency management
  • plugin demo

Key Facts

  • grails itself is made up of a collection of plugins

    • hibernate, webflow, gsp, etc.
    • grails core is essentially a set of plugins (about a dozen)

  • there are 300+ plugins available now

    • what a plugin can do is wide and varied

  • plugins are easy to create

    • don’t need to spend a ton of time learning the internals of the framework to create a plugin

  • plugins are easy to distribute
  • everyone is a plugin developer
  • well over 25 million lines of user contributed code in the plugin repository

    • searchable

      • automatically makes any domain class searchable

    • taggable

      • adds apis to tag domain classes

    • rateable

      • ratings for domain classes

    • quartz

      • for scheduling tasks
      • interesting because it adds a new concept to grails — “jobs”
      • adds create-job command to command line, has a jobs directory, etc.

    • gwt
    • weceem cms

      • example of a functional plugin as opposed to just providing new apis
      • this plugin contains views, controllers, domains, etc. as part of the plugin

    • feeds (rss and atom feeds)
    • iwebkit (iphone)

Common Use Case

  • you have a tag library
  • you have two applications
  • you want to share functionality
  • create a plugin!
  • grails create-plugin pluginName creates the plugin skeleton
  • grails 1.2 creates intellij project files

Plugin Structure

  • more or less identical to a grails application structure
  • can run the plugins as standalone apps

    • developing a plugin is the same as developing an application

  • only real difference is there’s a plugin descriptor in the root of each plugin

    • contains info about plugin version, grails versions supported
    • can also exclude specific resources when the plugin is installed
    • also numerous plugin hooks that can be accessed (doWithWebDescriptor, doWithSpring, etc.)

  • using packages is important–should always uses packages in your applications

Plugin Quick Start — 5 steps

  • grails create-plugin myPlugin
  • cd myPlugin
  • grails create-tag-lib myTagLib
  • grails package-plugin
  • grails install-plugin

Plugin Extension Points

  • normal grails development

    • tag libraries, controllers, etc.
    • the build
    • theses are very trivial to do

  • requires additional knowledge

    • spring configuration
    • new apis

      • addition of additional properties/methods to domain classes and domain controllers

    • new concepts

Plugin Types

  • relate to the “split” above
  • functional plugins

    • taglibs, controllers, extend the build, etc.

  • technical plugins

    • see above–spring config, metaprogramming, etc.

Examples

  • functional plugins

    • weceem cms
    • nimble

      • provides user management, integration with facebook, etc.

  • technical plugins

    • gwt
    • functional test

  • both functional and technical

    • spring security
    • searchable

      • adds search to domain classes, but also provides a complete search UI to your application

Functional Plugins

  • easier to understand
  • just like building a normal grails application
  • silos of functionality

    • forums, blog, search, etc.

  • used to create modular applications

Demo: Building a Functional Plugin

  • example: twitter clone

    • two different teams–web UI team, mobile team
    • underlying functionality is the same

  • good candidate for a plugin–need to share the domain model between the two apps
  • can install plugins in other plugins

    • e.g. can install both the iwebkit and the twitter domain model plugin into the iphone version of the app
    • can specify plugins and versions in dependsOn block in the plugin descriptor
    • when you package up your plugin it will bundle up the plugins on which your plugin depends and include them

  • can use BootStrap.groovy within plugins
  • can configure local plugin repositories and can specify order in which plugin repositories are searched

Certain Things that Plugins Cannot Package by Default

  • BootStrap.groovy, UrlMappings.groovy, DataSource.groovy
  • can create something like FooUrlMappings.groovy and that will get packaged

Some Tips

  • inline plugins

    • if you’re modularizing your entire application, becomes impractical to repackage and reinstall every plugin as they change during development

  • url mappings
  • jar dependencies
  • testing
  • plugin distribution

Inline Plugins

  • use plugins without installing them
  • prevents package/install cycle
  • great for modular application development
  • go to grails-app/conf/BuildConfig.groovy and set grails.plugin.location.”pluginName”=”../path/to/plugin
  • BuildConfig.groovy

    • not generated automatically in 1.1.1
    • lets you configure various aspects of the build, locations of generated files, etc.

URL Mappings

  • normal UrlMappings.groovy file is excluded from the package plugin process
  • if you want to define url mappings as part of your plugin, create a file called something like MyPluginUrlMappings.groovy and that will be included

Plugin Dependencies

  • grails supports transitive installs and plugin dependencies using dependsOn
  • can use ranges of versions for dependencies, e.g. hibernate:”1.1 > *”
  • to implement a “soft” dependency use loadAfter

    • def loadAfter = [“hibernate”]
    • can also specify loadBefore

Plugin JAR Dependencies

  • you can put jar files in the lib directory of the project just like applications
  • even better, in grails 1.2 you can define dependencies in grails-app/conf/BuildConfig.groovy
  • grails.project.dependency.resolution = {
    inherits “global” // inherit grails’ default dependencies
    dependencies {
    runtime “org.apache.ant:ant:1.7.1”
    }
    }
  • different scopes can be involved–build, runtime, test, provided (needed during grails run-app but not during WAR deployment)
  • this means the jar files are NOT included in the plugin packaging

    • allows application into which the application is installed to resolve the dependencies

  • in a traditional java project, the jar dependency list is flat
  • in grails, you have dependencies of the app, of the framework, and of any plugins involved

Testing

  • done just like a normal application
  • sometimes it’s useful to have classes used only for testing and not distributed with the plugin
  • use pluginExcludes in the plugin descriptor to achieve this
  • class MyPlugin {
    def pluginExcludes = [
    “ant/path/here
    ]
    }

Plugin Distribution

  • central repository

    • grails release-plugin

  • custom repository

    • can configure custom repos in BuildConfig.groovy
    • can also set this in settings.groovy in your user home directory

  • Grails separates notion of repos used for discovery vs. distribution (e.g. http for discovery, https for distribution)
  • can specify the repository into which to release the plugin when you run grails release-plugin
  • custom repos use svn for distribution

    • can use a basic file server for discovery

  • plugins don’t necessarily have to be open source to be in the central repository

    • need to specify the license
    • would distribute jars instead of source

Summary

  • developing grails plugins is very simple
  • functional plugins are an easy way to modularize your application
  • in part 2 we’ll be looking at how to develop technical plugins

Q&A

  • as part of modularization is there any integration with osgi?

    • not yet, but looking into it–probably next year there will be something more concrete

  • are there particular plugins that you would highlight that follow best practices or as good models to follow?

    • depends on what you want to do
    • for a functional plugin check out weceem cms–complete end-to-end with views, js, etc.
    • for a technical plugin check out Build Test Data (creates mock data for you)
    • quartz plugin is a good example of a plugin that adds a new concept to grails, new command line arguments, etc.

      • exercises the artefact api

    • SpringWS plugin adds notion of an endpoint to Grails
    • Ratable, Commentable, Featurable, and Taggable are great examples of modifying domain classes on app load

Session Notes – Spring WebFlow in Grails

Presenter: Joseph Nusairat, Integrallis About This Talk

  • discuss web flows
  • what are spring web flows
  • show some basics of webflow
  • live demo
  • Grails web flows didn’t really mature until Grails 1.1.1

What is Web Flow

  • allows for controlling the flow of items via steps, substeps, other flows
  • use when you want to control the sequence in which events occur in a series of events
    • e.g. buying a plane ticket on travelocity–goes through a specific series of steps
    • can’t go to point D without going through A, B, and C first
    • also support branches
  • control is not on the page but in a DSL
  • can keep components open for a longer period of time
  • where do you store the information for something like an uncompleted plane ticket order?
    • can store in the database, but would require cleanup for things that never make it to checkout
    • general way people have done this is via session data
      • check out spring memory management session recording on infoq
      • don’t want to use up a lot of your server RAM with sessions that are unused
  • at the end of the flow, data is persisted to a database or somewhere more permanent
  • when you remove the flow aspect of things from the pages themselves, it makes things more flexible and configurable
  • SEAM allows for different timeouts for conversations and sessions themselves

WebFlows in Spring

  • was new in Spring 2.0
  • great integration with JSF for rich UI
  • allows control over the scoping of objects for a limited period of time
  • cannot have multiple conversations
  • uses xml
    • xml is great for transferring objects, but not great for configuration
    • configurations aren’t generally that black and white

Creating a WebFlow

  • WebFlow in 1.2 M3 doesn’t work at the moment
  • GRAILS-5185
  • demo will be in 1.1.1
  • in 1.2 WebFlow is a plugin (grails install-plugin webflow)
    • in 1.1.1 it’s built in, but in 1.2 you have to install the plugin to use it
  • flows live in the controller
    • look just like an action, except ends with “Flow”
      • e.g. def bookingCartFlow = {}

Defining a View

  • views represent the individual pages
  • demo of hotel booking flow
    • “do you want to pay via paypal?” — decision point with branch
  • def bookingCartFlow = {
    start() {}
    }
    • whatever is defined first is the starting point–doesn’t have to be called start
  • DSL used to direct the flow, e.g. on(“submit”).to “end”

Domain Model

  • don’t have to worry too much about the domain model except for the object that’s used to track the conversation
  • Booking class is what’s used to track the conversation and isn’t persisted until the end
    • must implement Serializable in order to work

Creating a Controller and Actions

  • create a controller as per usual, but create an action ending with “Flow”
  • def bookingCartFlow = {
    start() {
    on(“next”) {
    // do work here
    log.info “inside start”
    }.to “stepA”
    on(“done”).to “end”
    }

    stepA() {
    on(“prev”).to “start”
    on(“done”).to “end”
    }

    end() {
    // define action state
    action {
    log.info “finish what you’re done with”
    }
    }
    }

  • make sure to follow the DSL–doesn’t necessarily error out if you aren’t following the DSL
  • examples here are all done in the controller but in a real app you’d be using a service layer
    • according to the docs transactional needs to be set to false, but it doesn’t work this way currently (1.1.1)
    • can do with transaction inside services if you’re trying to save states in a particular order

Views

  • in flows you can have subfolders below the view directory for the controller
  • class HotelController {
    def index = { redirect(action:’bookingCart’) } // this will go to the bookingCartFlow

    def paypalFlow = {
    pay() {
    on(“submit”) {
    log.info “Was it paid? ${params.paid}”
    }.to “evaluatePayment”
    }

    evaluatePayment() {
    action {
    if (params.paid == ‘yes’) {
    conversation.booking.paid = true
    return paidInFull
    } else {
    return paymentDeclined()
    }
    }
    }
    }

    def bookingCartFlow = {
    start() {
    action {
    log.info = “-start the booking-“
    }
    on(“success”).to “findHotels”
    }

    findHotels() {
    on(“showHotels”) {
    // find the hotel
    def hotels = Hotel.findAllByNameILike(“%${params.hotelName}%”, [max:10])
    [hotelResults : hotels]
    }.to “hotelListPage”
    }

    hotelListPage() {
    on(“view”) {
    flow.hotel = Hotel.get(params.id)
    }.to “hotelView”

    on(“back”) {
    }.to “findHotels”
    }

    hotelView() {
    on(“back”).to “start”
    on(“book”).to “bookingPage”
    }

    bookingPage() {
    on(“proceed”) {
    def booking = new Booking(params)
    booking.hotel = flow.hotel
    conversation.booking = booking
    if (!booking.validate()) {
    return error() // returns back to the page they came from and outputs errors
    }
    }.to “saveBooking”
    }

    saveBooking() { // the parens here are optional
    // no corresponding view to “saveBooking” so this is a decision node
    action {
    if (params.paymentType == “creditCard”) {
    return creditCard()
    } else {
    return paypal()
    }
    }
    on(“creditCard”).to “creditCard”
    on(“paypal”).to “paypal”
    }

    paypal() {
    subflow(paypalFlow)
    on(“paidInFull”)
    }

    creditCard() {}
    }
    }

  • to identify an event in a flow, you can use the name of a g:button as the event you want to trigger when the button is clicked
  • to use an event in a g:link, add event parameter to g:link, e.g. <g:link event=”view” … />

Scopes Available in Flows

  • request
  • params
  • session
  • flash
  • flow
    • lasts for the duration of the flow
    • removed when flow ends
  • conversation
    • lasts for the length of the flow and nested subflows
    • subflows are good for things like different payment methods–can be reused across multiple flows
  • best practice point: don’t refer to anything about flows or conversations in gsps
    • this ties the view to a specific flow or conversation and reduces the ability to reconfigure and reuse things

What are subflows

  • ability to create alternative flow paths
  • call subflows via flows
  • are their own flows themselves
  • name with “Flow” at the end
  • calling a subflow
    • subflow(subflowName)

Can you call to flows in different controllers?

  • yes, but it gets a bit funky
  • define flow in another controller as per usual, but declare the flow as static
  • in other controller, do def creditcardFlow = BillingController.creditcardFlow
  • still have to put the billing views under the hotel views as opposed to the billing views

How do you end the flow?

  • if a flow doesn’t do a transition or a redirect, the flow ends

Final thoughts

  • don’t call services with transactions–can cause unexpected problems
  • in grails 1.2 flows are a plugin
  • webflow moves objects from flash to request scope between transition states
  • don’t include the scope prefix when calling on the page
    • merge flow/conversation to local scopes

http://github.com/integrallis/grails_web_flow_demo

Session Notes – SpringOne2GX Day 2 Keynote

Adrian Colyer

  • a year ago at SpringOne was about when the acquisition of G2One was announced
  • Sky in the UK uses Groovy and Grails
    • so much simpler to write and run code
    • with groovy/grails we can create a new feature in a week instead of a month
  • Hyperic acquisition
    • better management tools and metrics
  • CloudFoundry
    • infrastructure as a service–bit too broad
    • focus on deployment of Java apps–“Enterprise Java Cloud”
  • VMWare acquisition of SpringSource

CloudFoundry Demo – Chris Richardson

  • demo of deploying a Java app on Amazon EC2 using CloudFoundry
  • upload apps to CloudFoundry, then can deploy to Amazon from there
    • can also upload sql scripts if necessary to generate/populate database
    • can also upload static resources if you want
    • uploaded war stored on Amazon S3
  • after this, deploy to EC2
    • options for splitting servlet container and db server on different instances
    • further options for specifying instance configurations on Amazon
  • CloudFoundry manages your Amazon instances
    • responds to failure
    • scales up/down
  • CloudFoundry also offers a lot of management actions, application monitoring, etc.
  • notion of “deployment blueprint”
    • can use deployment blueprint to deploy single app to different configurations
      • e.g. simple single instance deployment vs. apache fronting multiple load-balanced tomcat instances and multiple database instances all controlled by a management server

SpringSource Tool Suite

  • spring app tools
  • enterprise osgi development
  • flexible deployment options (cloudfoundry, vmware instances, vmware in data center)
  • STS Demo
    • CloudFoundry appears as a server type in the servers view in STS
    • can drag app to CloudFoundry to deploy
    • STS tools optimize WAR files by stripping out standard JAR files which are reconstituted on the other end

Cloud Types

  • CloudFoundry is the public cloud–runs on Amazon EC2
  • Private cloud–exists in the organization’s data center
    • like the model, like the flexibility, but don’t want to run on the public cloud
  • Personal cloud (running on a laptop)
  • mix and match types of clouds based on needs
  • public vs. private–currently much more interest in private cloud in the marketplace

Virtualization in the data center?

  • VMWare solutions
  • from infrastructure silos to infrastructure platform to infrastructure service
  • in many cases there is a direct binding between the application and the infrastructure that supports it
    • infrastructure becomes an anchor holding that application in place
  • virtualization is leading towards infrastructure being a platform onto which applications are deployed
    • specific application stacks are virtualized, and apps are deployed to this environment
  • currently virtualization is of more interest to the operations people
    • developers ask for a server on which they run an app, but they don’t know/care what’s going on at that level
  • new model is to expose the infrastructure to developers as a service
  • vCloud — internal, external, federated
    • based on vSphere technology
    • mix and match private/public clouds
    • same interface across multiple environments
  • CloudFoundry works with vCloud in addition to Amazon
    • adapters used to support different cloud environments

How does this add value to my enterprise Java apps?

  • knowledge of application blueprint, deployment blueprint, and infrastructure blueprint
  • easy management of things like firewalling across multiple VM instances
  • intelligent provisioning
    • when VMs are deployed they may or may not be on the same physical server
      • if this does matter, can declare an affinity between multiple VMs, or can specify that the instances should NOT be on the same physical server
  • optimized runtime: vMotion
    • can press a button to move VMs from one physical server to another with no interruption to the application
    • vmware platform separates out computing, memory, and storage
      • can move each of these independently without any interruption in service
  • vmware drs — distributed resource scheduling
    • can move VMs around dynamically based on load
    • heavily loaded apps can take unused capacity away from lightly loaded apps as needed
  • optimized runtime — vmware ft
    • single identical VMs running in lockstep on separate hosts
    • zero downtime, zero data loss failover for all VMs in case of hardware failure
    • no complex clustering or specialized hardware required
    • single common mechanism for all apps and OSes
    • all packets hitting first VM are replayed on the second VM behind the scenes
  • end-to-end management
    • hyperic hq can monitor all the vmware deployments from the infrastructure level down into the code itself

But do apps perform well on vSphere?

  • don’t judge performance based on running vms on your laptop
  • on the web tier, vmware has record performance
    • served more requests on a vm than on a physical box
    • 143,000 http ops/sec on a physical box
      • equates to 3 billion http requests a day, which is 3X eBay’s daily web traffic
  • appserver: near native performance
    • 95%+ of native on Specxpu and Specjbb
    • 95%+ native on specjvm
  • database performance
    • well-known oltp workload for testing
    • < 15% overhead
    • nearly 9000 database transactions per second
      • 5X number of transactions handled by visa for payment processing
    • near-perfect scalability from 1 to 8 cpus

Session Notes – Grails for the Enterprise

Presenter: Robert Fischer

What you’ll be getting for your time

  • j2ee friendly intro to grails
  • tour of grails functionality
  • practical day-to-day insights on using grails
  • live coding demo
  • argument for a single assertion: all enterprise web app development should be in grails
    • stunningly simple development
    • succinct code using a superset of java
    • sane defaults, straight-forward configuration
      • all the stuff you always use is pre-bundled
    • typing as deemed useful by developer
    • standard java deployment approach
    • springsource backed and here to stay
      • no need to worry about it going away
      • big community behind it that was around even before springsource acquisition

What is Grails?

  • web app dev framework and environment leveraging java and groovy
    • environment is often overlooked
    • easy to do development with vi and bash–need for IDE isn’t all that huge
  • convention-based mvc development framework
    • ruby on rails really introduced the idea of convention over configuration
    • grails takes this idea and applies it in the java space
    • powerful command-line tools
  • powered by pre-configured and pre-integrated spring, hibernate, sitemesh, junit, etc.
    • all the technologies you are or should be using

How would you like your grails?

  • conceptually think dynamic mvc framework
    • dynamic, succinct domain and controllers
    • view technology works naturally with html
    • run from source code check-out
    • new features via extensible plugin architecture
      • even the stuff built into grails is based on plugin architecture
  • actually approachable best-of-breed java stack
    • prepackaged java build system
    • builds a war to plug into existing deployments
    • hooks for existing spring and hibernate configs
    • support for other enterprise technologies

How does Grails fit the Enterprise?

  • what is the enterprise?
    • some people see this as “established, extensible, dependable”
    • some people see this as “bloated”
  • unique qualities of enterprise dev
    • large-scale apps with application ownership flux
      • people coding and gathering requirements on app will change over time
    • existence of user-developers
      • people who want/need to use your code but don’t want to know how the code works internally
      • google “robert fischer free toilet” to see his rant
    • out-of-control infrastructure
      • literal meaning: infrastructure I the developer don’t have control over
        • don’t have access to production databases, etc.
      • can also mean out-of-control in terms of there being a lot of different systems that the app needs to tie into

How does Grails fit in?

  • large-scale and ownership flux
    • conventional development
      • common style so doesn’t matter who wrote the code originally
    • built-in testing
      • strongly encourages writing of tests–major way to deal with ownership flux
    • groovy
      • more succinct language, easier to read
  • existence of user-developers
    • plugin architecture
      • “experts” can build plugins that “users” can leverage
    • direct java lib interaction
      • don’t have to think about how grails deals with the java class you just imported–it’s java
  • out-of-control infrastructure
    • big win here is Spring

Architecture of Grails

  • groovy
  • Model
    • GORM
    • Hibernate
      • can plug in other persistence mechanisms (JPA, Hadoop, CouchDB, etc.)
    • JDBC
  • View
    • GSP/Taglibs
      • taglibs are nice, straight-forward way to extend the codebase–much simpler than Java taglibs
    • sitemesh
  • Controller
    • Grails controllers
    • Spring MVC
  • pervasive
    • spring DI
    • spring transactions
    • servlet api
    • junit
    • ant (gant)
    • log4j
    • web.xml

Plugins

  • if you want other technology than listed above, there’s probably a plugin that does what you want
  • functional testing
    • G-Func, Canoo Webtest, Selenium, Fitnesse
  • RIA
    • Grails-UI, RichUI, GWT, Flex, YUI, IUI (for iPhone)
  • Database Management
    • autobase — runs database migrations
    • rails migrations plugin (you don’t want rails migrations!)
  • background tasks
    • BackgroundThread, Quartz
  • tons more — http://grails.org/plugins
    • rating system but don’t put too much credit in it

Autobase

  • manages database state using a non-linear collection of database change sets
    • Rails migrations are a linear path
      • assumes developer who made previous changes will be making future changes
  • leverages existing grails database automation to minimize effort
    • uses HBM -> DDL
    • HBM -> DDL assumes everything will be non-destructive
    • autobase handles destructive changes
    • uses embedded dsl in groovy; allows for things like dropColumn(), renameColumn()

BackgroundThread

  • provides a spring bean that executes arbitrary closures in the background
  • handles some awkwardness with hibernate sessions, provides thread logging and pooling

GORM Labs

  • transactional actions in controllers
    • services are transactional
  • .query — shorthand for .executeQuery
  • aggregate properties on domain classes
  • property errors on nested domain classes
  • human-readable messages

SubLog and Testing Labs

  • SubLog = Sublime Logging
    • static ‘log’ properties
      • by default logging is available only on instances of objects
    • dynamic ‘log’ properties
    • strips off slf4j and gives more direct access for log4j
  • testing labs
    • controller integration test case support

Your Grails Adoption Plan

  • start with a roughly green-field proof of concept web application
    • grails for reporting on an existing database is a great avenue for this
  • replace/supplement a service with grails
    • making grails an endpoint for an ESB
  • use GRAG on SourceForge to generate a db front-end
  • wrap an existing Java or PHP web app in grails and use web.xml (installed via “grails install-templates”) to map existing URLs to servlets
    • use url mappings to add new functionality in grails (e.g. http://myapp/g/newStuff)
    • PHP plugin gives you a PHP engine as a servlet–runs existing PHP code
  • do it and don’t tell anyone
    • ends up as a WAR
    • ask forgiveness later

Resources

  • live open source apps
    • Grails Crowd
    • grails.org
    • Groovy Blogs
    • Groovy Tweets
  • media
    • Groovy, Grails, Griffon podcast
    • GroovyMag

Live Coding/Q&A

  • anything you want to use in multiple apps, write as a plugin
    • grails generate-plugin PluginName
    • a plugin IS a grails application
      • only difference is it has a XXXGrailsPlugin.groovy file
    • plugin sizes are minimal addition to WAR files
    • once you’re done, do grails pacakge-plugin
      • creates a zip file containing the plugin
      • can do grails install-plugin zipfilename
    • need to set up a repository for plugins
    • when you go to production, it bundles the plugin into the war
    • note that plugins aren’t included in your application’s source–so need to point to a repository or figure out how to include those in source control
  • existing ant tasks can be plugged straight into gant
  • taglibs
    • easy to create and use
    • grails create-tag-lib taglibName
    • can take in attributes and the body between the opening and closing tag
      • e.g. def mytag = { attrs, body -> … do stuff … }
    • by default taglibs go into g prefix, e.g. <g:myTag/>
      • define a namespace in the tag library to give it a prefix other than g (static namespace = “whatever”)

Session Notes – Flex for Grails Developers

Presenter: Scott Davis

  • Flex plugin for Grails isn’t a simple plugin like the YUI plugin
    • technologies are too different from one another to fully integrate
  • What’s Flex?
    • free open source framework, but Flex Builder costs
    • lots of technologies floating around
      • some free of cost, some free and open source, some for pay
  • we are living in the era of the RIA
    • poorly defined
    • involves flex, air, silverlight, openlaszlo, ajax, java fx
      • java fx is applets redux–that’s how they’re deployed
        • some nice new stuff, but still 1995 technology with a new marketing plan
    • adobe has crushing lead in the ria space
    • lots of politics come into play–e.g. no flash player on iphone
      • apple converts all youtube content to quicktime to avoid having to use the flash player
  • have macromedia to thank for the ria term
    • idea was can’t use same technology already in browser for rich experience
    • solution is plugins into the browser
  • plugins aren’t new
    • applets introduced in 1995
    • lasting achievement of java applets is the warning asking whether or not you trust the applet
  • fast-forward to 2005
    • jesse james garret coins “AJAX” term
      • blog post discusses how web developers are envious of desktop developers
      • pointed to google suggest and google maps as examples
      • major thing is eliminating the page loads
      • amazing thing about google maps is they did it without a plugin
  • great divide (?)
    • can either have js + css + html, or can use a plugin
    • walls are starting to crumble however–hybrid development
    • apple desktop widgets
      • native part of OS but live in a different space
      • create in html, css, and js
      • use the webkit framework for rendering
      • gadgets in windows are similar
    • palm pre
      • webos
      • build apps with basic web languages
    • google chrome OS
      • OS based on chrome web browser
      • isn’t a scrim on top of OS like widgets and gadgets
    • notion of pulling up a web browser to run webapps will soon be seen as rather quaint
    • Adobe AIR is one attempt to eliminate the browser from the equation
    • idea of ubiquitous web also well represented by iTunes
      • webkit browser baked in
    • future of software development — of course it’s web enabled
      • the idea of web/not web will fade into the woodwork
  • twitter example of how ecosystem can develop around an API and core data
    • twitter doesn’t have to own the hardware and software

Nuts and Bolts of Flex

  • grails plugins assume you’re conversant with the acronyms and technologies involved with Flex
  • flash player is where flex apps run
  • flash player revs about every year, and the new players get adopted very quickly–huge adoption rate
    • 80%+ of users are on the most recent version
    • many, many more people run old versions of java as compared to flash
  • flash player on most mobile platforms but not on iphone
  • adobe recently released tools to allow for compilation of flex apps into native iphone apps
  • flash offers similar “write once run anywhere” experience
    • java: class files run in JVM, JVM native to OS
    • flash: swf files run in Flash Player, Flash Player native to OS
    • javascript model is a bit different–still breaking differences between the browsers
      • javascript libraries get around the browser incompatibilities
      • javascript engines in the browser aren’t pluggable/upgradable
  • ECMAScript — standard with 3 major dialects: javascript, actionscript, jscript
  • js engines
    • firefox: spidermonkey
    • chrome: v8 engine
    • IE: JScript 5.8
    • flash/flex: actionscript engine
  • adobe collaborating with mozilla
    • donated actionscript virtual machine (AVM2) to the mozilla foundation
    • tamarin will be used for javascript 2
    • same javascript engine as used in flash player
    • javascript is traditionally interpreted
    • V8 and Tamarin do a lot of just-in-time compiling
    • probably be years before this is a standard
  • swf is a partially open file format
    • specs are published, but adobe retains ownership
    • everyone can read/write swf files, but spec isn’t open for change
  • openlaszlo
    • because swf format is open, openlaszlo is written in lzx but generates a swf
  • flex is an sdk
    • big switch from the animation history of flash–flex is a ‘business toolkit’
    • flash player is free but not open source
    • adobe dabbling with open source–tamarin, open source sdk
    • flex builder isn’t even free as in beer
      • eclipse plugin
      • also plugin for intellij
  • here’s what we know so far
    • jvm (jre) == flash player
    • class (JAR) == swf
    • jdk == flex sdk

Deeper Dive Into Flex

  • two key technologies: mxml and actionscript
  • mxml–tag-based like html
    • declarative, nested hierarchy of widgets
    • mxml is the html/css analog in this environment
  • actionscript
    • ecmascript dialect
      • if you know JS do you know AS? yes and no
    • first official version of AS was in Flash Player 5
    • huge maturation with AS 2, even more with AS 3
      • AS has been sliding more and more towards Java in terms of strong typing, inheritance, packages, etc.

Flex Development

  • need flex sdk
  • similar manual install process as with groovy and grails
    • set up flex home directory as an environment variable, add flex bin to path
    • mxmlc compiles mxml/AS code into swf
  • can buy Flash Builder, but isn’t required for development
    • development experience isn’t nearly as good without Flash Builder
  • IntelliJ has Flex capabilities as well (only in pro version)
  • Google provides SWCs to incorporate google maps into flex appss

Grails Plugins

  • four plugins
  • GraniteDS Flex Plugin–seems to be most mature and well documented
    • includes GraniteDS for data services
    • originally required JPA, not GORM
    • GORM support now in the plugin (experimental)
    • install the plugin, annotate the services and controllers
    • can then generate AS3 domain classes as well as the flex app itself

Session Notes – A Practical Take on GORM

Presenter: Robert Fischer
Author: Grails Persistence with GORM and GSQL
SmokeJumperIT — Grails consulting and training

Agenda

  • Overview of GORM
  • Intro to HQL
  • tour of GORM labs
  • tour of GORM plugins
  • extending GORM

GORM 101

  • Grails Object Relational Mapping
  • extensible and dynamic data access API

    • dynamic — as you describe to grails what’s in your application, you get more functionality automatically

  • hibernate wrapper (sometimes)

    • can use GORM outside of grails
    • transaction handling
    • data cache
    • schema generation/update system

  • even with the no SQL movement you still need an object to something mapping

Basic GORM Conventions

  • ./grails-app/domain
  • domain classes define tables
  • instance properties define columns
  • static properties define configuration

    • e.g. static hasMany = [bazzes:Baz], static mapping = { … }
    • any time you see this, some sort of Grails magic is going to be happening behind the scenes

  • automatic id and version

    • GORM assumes you want an artificial ID and you want to work with optimistic locking
    • natural keys are enticing, but always become a problem
    • can opt out of these, but not encouraged

  • opt-in timestamping using dateCreated and lastUpdated
  • everything beyond these basics is probably boundary conditions or a need to extend GORM in some way

GORM Classes (Domain Classes)

  • even with a simple class Baz {} declaration you get tons of functionality
  • better to err on the side of having a domain class for everything in your app to get counts, lists, findByVersion, etc.
  • constraints used for data integrity

    • note that if you’re using existing data you can pull “bad” data back but when you try to save, the constraints will kick in and fail so you’ll have to deal with the bad data at that point

  • mapping — depending on how you define things may or may not get mapped

    • String foo (declared string) = mapped
    • bar (only defined via its getter and setter but not declared) = mapped

      • this will always be dirty
      • can come in handy for implementing transforms in an overridden setter

    • bar2 (default artificial property) = not mapped

      • can come in handy for tracking schema changes over time without having this reflected in the database

    • foo2 (default natural property) = not mapped

      • the default part is the problem, not artificial vs. natural

    • baz (runtime added property) = not mapped

      • at application startup grails looks at the compiled structure of the classes to generate hibernate mappings

Underappreciated Methods

  • Foo.lock(id)

    • pulls an object back and locks it from being updated from other processes
    • can solve transactional issues
    • does for update in oracle, currently does nothing in mysql (but supposedly this is getting implemented)

  • Foo.read(id)

    • pulls a record from the database and says “I’m not going to modify this”
    • if changes are made on the object after read, they’re ignored
    • saves cache since it won’t be cached

  • Foo.findAllWhere(bar:’one’,baz:true)

    • can be implemented as Foo.findAllByBarAndBaz(‘one’, true) but is more concise

  • Foo.executeQuery(hql) and Foo.executeUpdate(hql)

    • can use executeUpdate on update, delete, insert
    • allows you to take a bit more ownership of what’s going on with the database and the generated sql

Hibernate Query Language (HQL)

  • like SQL but with a lot less pain

    • working directly with objects and relationships as opposed to having to write sql joins manually
    • if you’re finding yourself writing sql and manually building up objects, chances are hql can handle what you’re doing more simply

  • leverages mapped classes and properties
  • provides abilities to construct objects and maps directly in queries
  • one major limitation: error reporting is miserable

    • if you screw up your hql statement in a way that makes sense to the parser, error messages are good
    • if the hql doesn’t make sense to the parser, you just get a null pointer exception from somewhere deep in hibernate
    • hibernate team is aware of this and working on improving

HQL for SQL-heads

  • query on objects, not on database tables
  • objects are normally returned
  • select * can be left off (just “from Foo”)
  • no need to join *-to-one relationships: from Foo f where f.bar = ?
  • traverse many-to-many relationships via a joining on object relationships

    • from Foo f join f.bazzes b
    • can say “fetch join” to eagerly pull back bazzes for Foo

  • on existing databases–can use GREG (or GRAG?) — Grails Application Generator

    • generates domain classes, etc. from an existing database
    • falls down if some company mandates all db access is through storedprocs

      • problem for Hibernate in general
      • fighting against the GORM conventions so hard that it makes it very difficult
      • plugin available to specify different databases for different domain objects–can get around some of this going this route

HQL Tips and Tricks

  • encapsulate the HQL in methods

    • don’t put it in a service–put it on the domain class where it belongs
    • HQL is referencing properties, so if the property name changes you have to track all references down if this isn’t in the domain class

  • use $Token.name to save having to write out package names

    • standard groovy references–resolves the same way

  • use simple interpolation (${}) to add a bit of dynamism to your query
  • do not ever directly interpolate external values into hql

    • sql injection attack vector
    • always pass these in as parameters

GORM Labs

  • plugin
  • tons of added methods to GORM

    • Foo.query — shorter reference for HQL queries
    • for any property on a class you get

      • min, max, avg, sum, count, countDistinct on each property (e.g. Foo.minBar, Foo.maxBar, etc.)

    • Foo.connection — access to current db connection
    • Foo.sql
    • Foo.session
    • Foo.flush()
    • $foo.errors — nicer representation of errors
    • Foo.withCriteria — allows ordering by nested properties (only works for one to one properties)
    • Gorm.connection, Gorm.flush, etc.

      • makes calls directly on gorm without having to refer to an arbitrary domain class

    • transactional actions in controllers

      • got him flamed on the list since this is supposed to be in services, but many people do db stuff in controllers

    • HasMany pagination/counts
      foo.bars(max:2, offset:3)
      foo.countBars
    • session object dehydration

      • if an object is thrown into the http session and it has an id, the id gets persisted in the session and it can be used to pull back the domain class if the object is attempted to be retrieved after the hibernate session has died

Favorite GORM Stunt: Transparent API Switch

  • assume there is a slow gorm api call
    Foo.findAllByBarOrBaz(bar, baz)
  • define a static method with the api call method name and hand-optimized sql
    def ids = Foo.sql.rows(query)*.id
  • return the (possibly cached) instances
    return Foo.getAll(ids)

Other GORM Plugins

  • audit logging

    • automatically keeps an audit trail on database activity

  • extended GORM mappings
  • GORM HBase (Hadoop HBase)
  • GORM JPA

    • exists because of Google App Engine and the BigTable JPA functionality

  • explicit insert

    • allows you to do an explicit insert as opposed to save() which might do an insert or an update

  • datasources (per-domain class data source)
  • multitenant (per-tenant data source)

    • tenant attached to an HTTP request
    • great for situations where you have multiple clients each of which has their own datasource

  • system itools

    • plugin for IBM itools

  • DTO
  • joda-time

    • makes Joda-Time compatible with java.util.Date
    • makes all Joda-Time structures persistable to the database

Extending GORM The Easy Way

  • create plugin based on GORM Labs
    dependsOn = [gormLabs: ‘0 > *’]

    • lets you take advantage of high-level stuff that GORM labs fixes

  • do metaClass mangling in doWithDynamicMethods
  • retrieve domain class metaClasses by application.domainClasses*.clazz

Current FOSS Projects – Shameless Cry for Help

  • Liquibase-DSL / Autobase
  • Bitescript (was JVMScript)
  • GORM Labs, Testing Labs, Sublog
  • JConch

Q&A

  • interesting plugins for other frameworks/languages

    • PHP plugin — Grails can wrap existing PHP apps

  • any cases where you wouldn’t use GORM/Hibernate?

    • if storedprocs are required, not a good fit
    • in pretty much every other case hibernate works well
    • spent some time doing rails, perfer gorm method of doing things as opposed to activerecord

  • in production databases, what’s the best practice for the datasource setting? (e.g. create, update, create-drop, etc.)

    • schema management is a difficult problem if you want 100% uptime
    • changing from one schema to another can cause some issues with hibernate
    • autobase plugin fixes some of these problems — allows you to run migrations but have to write migrations by hand at this point