38
1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin, Ari Miller

1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Embed Size (px)

Citation preview

Page 1: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

1

Grails in the Enterprise 2010L.A. JUG April 4th 2010By Todd R. Ellermann

With Key Contributions from VT team members: • Ken Ellinwood, David Benjamin, Ari Miller

Page 2: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Todd R. Ellermann

B.S. Computer Engineering University of Arizona MBA Arizona State University (Certificate in

Software Engineering Management) V.P. of Engineering for VirtualTourist.com Java Certified 1998 http://www.betterwebapp.com

Wrote the same web application in 8 languages (screencast, source code, measured silly things like screen cast time and lines of code etc…)

toddecus (aim, twitter, yahoo, skype etc…) [email protected]

Page 3: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

VirtualTourist.com

Expedia>TripAdvisor>VirtualTourist Online Travel Community with emphasis

on Real people writing reviews of Hotels and talking about things to do.

Monetize through advertising (CPM,CPC) VirtualTourist.com Stats:

8.4 Million Visitors 30 Million PV / Month 1.2 Million Members 1.7 Million Travel Tips 3.7 Million Photos 10 Year anniversary this year!

Page 4: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

What we are going to cover

Why we chose Groovy/Grails

Quick “what is grails” Grails Versions Ecosystem around Grails

Plug-ins IDE/Tools Building Grails Apps

Convention/Configuration Under The Hood

Spring Hibernate Sitemesh

Use of Dynamic Language Subclass vs. Closure

GORM Multiple-data sources GSQL URL Mapping Grails Console Testing Hot Deployment Normal Java stuff still

works Deployment Environment JMX et al… Web Services VT Today

Page 5: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

VT June 2008

PHP Batch

Page 6: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Intro to Groovy / Grails

Groovy ( 1.7.1 latest) Dynamic Scripting Language Runs on JVM Java Syntax - Semi-colons + Closures +

heredoc http://groovy.codehaus.com

Grails (1.2.2, or 1.3-RC1) Code By convention Framework Best in Breed Java under the hood DRY (Don’t Repeat Yourself) http://www.grails.org (SpringSource)

Page 7: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Do DEMO HERE

Create App Generate GORM objects Generate controllers

Def scaffold = true Generate all

Run-app show validate(), errors etc.. Passing from a map to a

domain.properties

Page 8: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Grails Versions

Grails 1.0 (February 4, 2008) (1.0.5 latest) Rough but stable (1.0.3 very different than 1.0.4-5) 1.0.4 probably should have been full release Intro of GORM DSL over hibernate

Grails 1.1 (March 10,2009) (1.1.2 latest) What we are on today (1.1.1) + Groovy 1.5.7 Performance improvements (GSP optimization) Testing ENUM Maven Log4j DSL

Grails 1.2 (Dec 23rd, 2009) (1.2.2 latest) HOT!!! Dependency Resolution (ivy) Named Queries Performance Improvement (io push+precompile) 2-

3x faster SPRING 3.0 + Spring Annotation Detailed Datasources Switch to Tomcat as default container (Spring

source influence) No technical reason provided other than springsource

knows tomcat better Run exact Test not all tests (improved developer

cycle)

Grails 1.3-RC1 ???? Uhhh…OK

Move to Groovy 1.7

More maven crap

Grails 2.0 ???? Not sure why I care

OSGi Plugins

dependency declaration

Security abstraction

Page 9: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Plug-in Ecosystem List

388 plug-ins up from 35 two years ago

Jetty/Tomcat Quartz AppEngine GrailsUI Searchable Acegi Shiro/Nimble (jSecurity) Weceem (cms) Datasources Hibernate Search

Simple commands:grails uninstall-plugin tomcatgrails install-plugin jetty

P6spy GSolr Jquery/YUI Paypal Xfire Multi-Tenant (web

hosting) Jndi Ldap Spring MVC, cache, WS Flex Gorm

VERY Easy to write we have a few internal VT plug-ins

Page 10: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Plug-in Ecosystem Problems

Abandoned plug-ins Compatability of two different plugins:

Multi-tenant collides with anything that gets into hibernate interception

Plug-in dependency/assumptions not clear:

Weceem imports Acegi Nimble assumes shiro, spock, compass et al…

What Version of Grails does this plug-in work with? (Getting better)

Page 11: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Tools IDE

IntelliJ V 8 was a little rough still V9 is useable, still a little rough in areas

VI Emacs Eclipse is WAY behind Netbeans is OK (from what I hear) Groovysh GrailsConsole

Page 12: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Maven/Gradle/Grapes/GANT Grapes is groovy grab() method (ibiblio etc..)

GANT is DSL on top of ANT (no more xml) Gradle is what Maven should have been (according to Gradle guys not me, verdict not in yet)

Not much tool support yet No XML Can call ANT, GANT or Maven pom goals etc..

Maven Grails Plugin (Maven 2.0.9 and above) Tool support .m2/settings.xml

<pluginGroups> <pluginGroup>org.grails</pluginGroup> </pluginGroups> Create Grails project

Grails built on Hudson with Maven Gradle (recent change)

import com.jidesoft.swing.JideSplitButton@Grab(group='com.jidesoft', module='jide-oss', version='[2.2.1,2.3.0)')public class TestClassAnnotation { public static String testMethod () { return JideSplitButton.class.name }}

mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-4:generate \ -DarchetypeGroupId=org.grails \ -DarchetypeArtifactId=grails-maven-archetype \ -DarchetypeVersion=1.2.0 \ -DgroupId=example -DartifactId=my-appMvn initializeExample is from here: http://www.grails.org/Maven+Integration

Page 13: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Convention over configuration

Directories mean something.grails-app/conf : data sources, spring, url mapping, configs,Bootstrapgrails-app/domain : map these to the databasegrails-app/controllers : abstraction above servlet, Command Objectsgrails-app/views : GSP’s and Templatesgrails-app/taglib : custom taglib’sgrails-app/services : Singleton by default Tx or NoTx

Names mean something. FooService.groovy FooFilters.groovy FooTagLib.groovy FooController.groovy FooCommand.groovy also @Validateable

Page 14: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Under The Hood: Spring

/conf/resources.groovy (Spring DSL)

import org.springframework.context.*

class FooController implements ApplicationContextAware { ApplicationContext applicationContext CacheService getCacheService() { applicationContext.getBean(“cacheService”)}}

beans = { switch(GrailsUtil.environment) {

case "test": serviceLocator( com.vtourist.hotel_tool.testing.ServiceLocator4Tests) {} locationService( com.vtourist.service.location.client.MockLocationService) {}

break default: serviceLocator(com.vtourist.common.service.DefaultServiceLocator) {

jndiName = DefaultServiceLocator.DEFAULT_JNDI_NAME } locationService(com.vtourist.service.location.client.LocationServiceImpl, ref('serviceLocator'))

{} break }

locationDetailsCache( com.vtourist.service.location.client.LocationDetailsMRUCache, 1000) { locationService = ref('locationService')

} }

• Application Context Aware

Page 15: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

15

Grails 1.2 More Spring

From Grails Release Notes: http://www.grails.org/1.2+Release+Notes

In this example, going to /hello.dispatch will execute the handleRequest() method and atempt to render either a GSP or JSP view at grails-app/views/hello.(jsp|gsp)

Page 16: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Under The Hood: Hibernate

location.hbm.xml override autowire domain object mapping

Dynamic Finders: def loc = Location.findByName(“El Segundo”)

There are also “by example”:   def loc = Location.find( new Location(name:’San Juan’)

)

Using GORM DSL to create Criteria Query

Page 17: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

17

Hibernate Continued

SQL Get to use Caches and automap to domain objects

Note: Use of “heredoc” style GString. Really useful with SQL and inline Templates (emails et al…)

Page 18: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

18

Actual SQL executed

Hibernate:             SELECT L.ID as ID32_0_, L.cities as cities32_0_, L.latitude as latitude32_0_, L.level as level32_0_, L.longitude as longitude32_0_, L.name as name32_0_, L.NextLevel as NextLevel32_0_, L.Parent1 as Parent8_32_0_, L.Parent2 as Parent9_32_0_, L.parent3 as parent10_32_0_, L.parent4 as parent11_32_0_, LM.Location as Location23_1_, LM.Cities as Cities23_1_, LM.HotelPics as HotelPics23_1_, LM.HotelTips as HotelTips23_1_, LM.Members as Members23_1_, LM.Pictures as Pictures23_1_, LM.Tips as Tips23_1_              FROM Location L,                   LocationMeta LM             WHERE ID32_0_ = Location23_1_                   AND                   Tips23_1_ >= ?Bangkok has 10656 tips

Page 19: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Under The Hood: Sitemesh GSP == JSP + JSTL + Grails Taglib + Groovy Taglibs are Sooo Easy

Templates sitemesh _rightWellGoogleTextLinks.gsp <g:render template=”rightWellGoogleTextLinks"

model="[’textLinksResult':textLinksResult]" />

class VirtualTouristTagLib { static namespace = ‘vt’ def locationService def locationForLocationName = { attrs, body ->

def locationName = attrs[’locationName'] def location = locationService.getLocationByName(locationName)if(location != null) { request.setAttribute(’location', location) out << body() }

}}

<vt:locationForLocationName locationName=“$[locationName]”> <h1>This city ${locationName}‘s parent location is ${location.parent.name}</h1></vt:locationForLocationName>

Page 20: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Dynamic Method Invocation

• Groovy allows method names to be specified in Strings – e.g., instance.”foo”() calls the instance’s foo() method.

• Can be used to simplify method dispatch.

Page 21: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Closures vs Subclasses

Template Method pattern revisited from GOF

abstract class BaseAlgorithm { protected int value1, value2;

public abstract int calculate();}

class SubAlgorithm extends BaseAlgorithm {{ public int caculate() { return value1 + value2; }}

1.2.3.4.5.6. 7.8.9.10.11.12.13.14.15.16.17.18.19.20.

class Algorithm { int value1, value2

int calculate( def closure) { return closure( this) }}

a = new Algorithm( value1: 40, value2: 2)

println a.calculate( { algs -> algs.value1 - algs.value2 })

Java Version

Groovy Version

Page 22: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

GORM Datasource DSL

• Bind all domain objects to this datasource depending on environment.

• Access to hibernate directly• Cache Control• GORM will “create” tables

automatically in test,console but “validate” in other ENV’s

• Can use JNDI in Integration, QA, and Production

Page 23: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Datasources Plug-in

DatasourcesHow do I bind GORM objects to 2 or more datasources?

Note the binding of domain objects to different domain.Not shown. The damn tables have to also exist in our original VT schema!

Note the lack of bound domains for 3rd datasource, now we can use that for “GSQL”

Be careful with GSQL et al… not the same rules for releasing connections back to the pool.

Future: How do I have some objects bound Read/Write and some bound Read Only to a slave?

Page 24: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

GSQL/JDBC

Be careful there are differences between getting your Sql object from jndi/ datasources vs instantiating connection live.

Page 25: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Grails Console

Demo Console Quick turn around to answer the

question what happens when/if?

Page 26: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

26

Grails Controller -- Command

DTO, Details Object, or Grails Command

Page 27: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Unit Testing That Controller

Page 28: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

HotDeploy

Everything not “injected” Domain out Command out

Controllers, GSP’s, Views, some services

Page 29: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Groovy = Java – Junk + Killer Ecosystem

Everything you can do in Java I can do better/faster or at least the same:

Logging (log4j) Quartz Annotations JNDI SpringSecurity (ACEGI) JMS Xstream JDBC Continue to abuse the J2EE label etc…

Page 30: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

WAR on the JVM

grails [env=production] war Compiles source to byte code Includes groovyAll.jar Includes 53 other jars (grails, spring

hibernate,etc..) Precompiles gsp Creates fooApp.war with environment

settings of “production” Everyone with existing “J2EE” infrastructures is

going to love this. It’s like the linux server in the closet.

“So I skipped the EJB’s and finished a year early… does mgmt really care… No!” -- unknown

Page 31: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

“Services”

The defaults of Grails convention-over-configuration encourage a service layer within the application

Service classes are Spring singletons(configurable) dependencies are injected by Spring IOC dependencies include other services and data access layer

"domain" objects Local clients easily access services

service singletons are injected by Spring IOC Controllers do the following to access a local service:

class AbcController { def xyzService // causes Spring to auto inject xyzService def doStuff = {

def arg1 = params.arg1….result = xyzService.businessMethod( arg1 )….

}

Page 32: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

URL Mapping

URL DSL easy to create SEO friendly URLs or even map legacy URL’s to new controllers.

Also interestingly easy to take true RESTful approach

Page 33: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

33

JMX example

Exposing a Grails Service to a remote client requires installing plug-ins for desired protocols

add the protocols to a static member list on your service class

class MonitorService { static expose = ['jmx'] def counter = 1 def incrementCounter() { ++counter } }

What if I could use this to tell the front end applications which service servers were currently available and prevent downtime as new code bases were deployed?

Page 34: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

34

JMX Console

Page 35: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

VT Today

Page 36: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

What we covered

Why we chose grails

Grails Ecosystem and Versions

Spring Hibernate Use of Dynamic

Language

Developer cycle time GORM + GrailsConsole

Testing Java Me Too! Deployment

Page 38: 1 Grails in the Enterprise 2010 L.A. JUG April 4 th 2010 By Todd R. Ellermann With Key Contributions from VT team members: Ken Ellinwood, David Benjamin,

Sad attempt at Groovy Humor

class BestTravelWebsite { def domainName def parent def memberCount def photoCount def travelTipCount def UniqueVisitors def pageViews}

def virtualTourist = new BestTravelWebsite(domainName:”www.virtualtourist.com”,parent:tripAdvisor,memberCount:1,200,000,photoCount: 3,702,063,travelTipCount:1,781,378,uniqueVisitors: 8,400,000,pageViews: 32,000,000)

def expedia = new BestTravelWebsite(domainName: ”www.expedia.com et al….”, tickerSymbol: ”EXPE”)

def tripAdvisor = new BestTravelWebsite(domainName:”www.tripadvisor.com et al…”,parent:expedia)