Grails Advanced


Published on

More Enhancements to Grails:
Topics covered:
Grails Plugins
Restful API
Integration Tests
What’s new in grails 2.0
What’s new in grails 2.1
What’s new in grails 2.2
How to upgrade plugins

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Grails Advanced

  1. 1. By- Saurabh Dixit
  2. 2.  Grails Plugins Resources RestfulAPI IntegrationTests What’s new in grails 2.0 What’s new in grails 2.1 What’s new in grails 2.2 How to upgrade plugins
  3. 3.  Grails Plugins: InstallGrails plugins Create a new plugin Use custom plugin in multiple applications
  4. 4.  Installing Plugin Install-plugin spring-security-core Using s2-quick start
  5. 5.  Configuration in config file: importgrails.plugins.springsecurity.SecurityConfigType; grails.plugins.springsecurity.securityConfigType =SecurityConfigType.InterceptUrlMapgrails.plugins.springsecurity.interceptUrlMap = [/:[ ROLE_SUPER_ADMIN, ROLE_ADMIN, ROLE_USER ],/login/**:[ IS_AUTHENTICATED_ANONYMOUSLY ],/logout/**:[ IS_AUTHENTICATED_ANONYMOUSLY ],/register/**:[ IS_AUTHENTICATED_ANONYMOUSLY ],/userInfo/**:[ ROLE_SUPER_ADMIN, ROLE_ADMIN,ROLE_USER ]
  6. 6.  Including resources - using tags: Declaring modules: You can declare resource modules in bothapplications and plugins.There are a couple of waysof doing this, but the most common approach is toadd one or more dedicated artifacts to the project.For an application this might be grails-app/conf/ApplicationResources.groovy.
  7. 7.  modules = { core { resource url: js/core.js, disposition: head resource url: js/ui.js resource url: css/main.css resource url: css/branding.css resource url: css/print.css, attrs: [media: print] } utils { dependsOn jquery resource url: js/utils.js } forms { dependsOn core, utils resource url: css/forms.css resource url: js/forms.js } }
  8. 8.  "core", "utils" and "forms" are the names of ourapplication modules. You can also see that the "utils" module depends on"jquery“ If we look a bit deeper into the above moduledefinitions, we can see that individual resources aredeclared within a module using "resource" plus aURL.This URL is the location of the resource relativeto the web-app directory in your project. If you wish,you can also add extra attributes for fine-grainedcontrol of resources, in particular via the"disposition" setting.
  9. 9.  There are two standard dispositions: "head",meaning that a resource goes inside the<head> element, and "defer“. By default,CSS files have a disposition of"head" while Javascript files use "defer"
  10. 10.  Including resources in a page As you know, you previously had to declareall your CSS and Javascript links explicitly inyour layouts and views. So how does this change with the Resourcesplugin? Instead of putting in links toindividual resources, you declare whichmodules your page requires, which makes formuch conciser <head> blocks.
  11. 11.  In addition, you specify where in the page the resource linksshould go. Heres an example of a very simple layout usingResources:<html><head>...<r:require modules="common, jquery"/><r:layoutResources/></head><body>...<r:layoutResources/></body></html>
  12. 12.  <r:require> tag tells Grails which staticresources to include in the page <r:layoutResources> tags specify where thelinks should go. You should have two <r:layoutResources>tags: one in <head> and the other in <body>.Any resource with a disposition of "head" willgo where the first one is, while those with adisposition of "defer" will be inserted at theseconds location.
  13. 13.  Ad-hoc resources The Resources plugin calls inline images andscripts "ad-hoc resources".These typicallyarent declared in modules and are simplyprocessed as and when they are encounteredin the page.A standard inline image link lookssomething like: <imgsrc="${resource(dir:images,file:grails_logo.png)}" ... />
  14. 14.  Adding resources on the layout->main <r:require modules=" bootstrap,bootstrapNavigation,validationEngine,maskedInput,smartPagination, jqueryTmpl, jqueryUi, jquery,toolTip " /> <g:layoutHead /> <r:layoutResources />
  15. 15.  Adding Layout file to view: <g:applyLayout name="main" /> In this way you need not to include resourceson every view
  16. 16.  Web services are all about providing a web API onto yourweb application and are typically implemented in either REST or SOAP.
  17. 17.  REST: Using a RESTful solution▪ The first step in creating an API for an application isdeciding what it should allow clients to do.▪ After all, if a feature isn’t available in the API, a clientcan’t use it.▪ Working out what should go into the API isn’t always aneasy task, but during development you have scope toexperiment. Once the API is published, that’s it.You haveto avoid changes that will disrupt those software clientsthat rely on it.
  18. 18.  Adding elements to an API often causes fewerproblems than changing or removing existingelements. A good strategy is to start minimally and grow theAPI as required. REST is not really a technology in itself, but more anarchitectural pattern.
  19. 19.  REST is very simple and just involves using plain XML orJSON as a communication medium, combined with URLpatterns that are "representational" of the underlyingsystem, and HTTP methods such as GET, PUT, POSTand DELETE.Def handlePosts = {if (request.method == "GET") {...}else if (request.method == "POST") {...}} Each HTTP method maps to an action type. For example GET for retrieving data, PUT for creatingdata, POST for updating and so on. In this sense RESTfits quite well with CRUD.
  20. 20.  URL patterns: The first step to implementing REST with Grails isto provide RESTful URL mappings:static mappings = {"/product/$id?"(resource:"product")} This maps the URI /product onto aProductController.
  21. 21.  Each HTTP method such as GET, PUT, POST andDELETE map to unique actions within the controlleras outlined by the table below:Method ActionGET showPUT updatePOST saveDELETE delete
  22. 22.  You can alter how HTTP methods are handled byusing URL Mappings to map to HTTP methods:"/product/$id"(controller: "product") {action = [GET: "show", PUT: "update", DELETE: "delete", POST: "save"]} However, unlike the resource argument usedpreviously, in this case Grails will not provideautomatic XML or JSON marshalling unless youspecify the parseRequest argument:"/product/$id"(controller: "product", parseRequest: true) {action = [GET: "show", PUT: "update", DELETE: "delete", POST: "save"]}
  23. 23.  Issuing a request with a method other than GET orPOST from a regular browser is not possible withoutsome help from Grails. When defining a form you can specify an alternativemethod such as DELETE:<g:form controller="book" method="DELETE">..</g:form> Grails will send a hidden parameter called _method,which will be used as the requests HTTP method. Another alternative for changing the method for non-browser clients is to use the XHTTP-Method-Override tospecify the alternative method name.
  24. 24.  XML Marshalling – Reading: The controller can use Grails XML marshalling support toimplement the GET method:import grails.converters.XMLclass ProductController {def show() {if ( && Product.exists( {def p = Product.findByName( p as XML}else {def all = Product.list()render all as XML}}..} If there is an id we search for the Product by name and return it,otherwise we return all Products.This way if we go to /products weget all products, otherwise if we go to /product/MacBook we onlyget a MacBook.
  25. 25.  Using firefox Poster addon: Install poster plugin on the firefox, and thenfind it on the tools tab, and then you will beable to send http requests to your applicationand test your rest API requests andresponses.
  26. 26.  1. Unit testing: 2. FunctionalTesting 3. IntegrationTesting
  27. 27.  UnitTesting: Why are we starting with unit tests? But as you’ll see later, you can also use Grails integrationtests for “unit testing” if you want. There are two primary advantages of unit tests overintegration tests:▪ They’re quicker to run.▪ You can run them from within your IDE.
  28. 28.  Useful assertions available to your test cases:assertEquals(expected, actual) Compares two values or objects for equality usingthe equals() methodassertTrue(value) Checks that the given value is true after beingcoerced to a BooleanassertFalse(value) Checks that the given value is false after beingcoerced to a BooleanassertNull(value) Checks that the given value is nullassertNotNull(value) Checks that the given value is not nullassertSame(expected, actual) Checks that two objects are the same instanceassertArrayEquals(expected,actual)Compares two arrays for equality, checking thatthey have exactly the same elementsshouldFail(type, closure) Checks that the given closure throws an exceptionof the given type, or any exception if type is omitted
  29. 29.  Who are you mocking? The process of mocking involves providing fakeversions of classes or methods that can be used inplace of the real implementations. The cool thing is that you can control the behaviorof the mock object or method, so you can passknown data to the object under test. Mocking can be used at any level of testing, butit’s most commonly associated with unit tests.
  30. 30.  Many of the methods provided byGrailsUnitTestCase are used to mock the dynamicproperties and methods that would normally beinjected into classes by Grails. All of the mock*() methods provided byGrailsUnitTestCase use metaclass programming toadd mock properties, methods, and objects.Thatmeans you can add your own or override theexisting ones to fine-tune the behavior.
  31. 31.  In addition, the mock validation performs realSpring databinding, so the errors property is a real instance of Spring’s Errorsinterface.This allows you to check formultiple constraint violations on a singlefield.
  32. 32.  IntegrationTesting: Where unit tests are about testing individual,atomic units of functionality (like classes and theirmethods), integration tests are designed to testlarger parts of an application, such as a controllerand its dependencies together. The main focus is on ensuring that the units worktogether correctly—that they integrate properly.
  33. 33.  In Grails, integration tests appear on the surface to beunit tests. In fact, if you create a new integration testwith this command,grails create-integration-test Book The fundamental difference is that integration tests runinside a full Grails environment, with a running databaseand all those dynamic methods and properties thatyou’re used to. You don’t have to mock any of them. For all intents andpurposes, the tests run against a real instance of yourapplication.
  34. 34.  The main thing missing is the servlet container, thelack of which has certain repercussions. Here is a summary of what works and what doesn’t: All plugins that don’t exclude the test environment are loaded. BootStrap is executed. Spring application context is fully populated. Domain classes work against a live database (an in-memory HSQLDB,by default). All dynamic methods and properties are available. Mock versions of the servlet request, response, and session are used. NoGrails or servlet filters are executed. URL mappings have no effect. Views can’t be tested.
  35. 35.  Under the hood: Each integration test is run inside a transactionthat’s rolled back at the end of the test.Thismeans that no changes are committed to thedatabase. Also, the default Grails environment fortests is “test”.class MyController {def myServicedef show = {def items = myService.fetchItemsFor(params.userId)[ itemNames: items.collect { } ]}}
  36. 36.  what if the service method returns null instead?There’s no reason it can’t do so, but now you can seethat the controller will throw a NullPointerExceptionbecause of the code items.collect {...}.class MyControllerTests extends GroovyTestCase{def myServicevoid testShowNoItems() {def myController = new MyController()myController.myService = myServicemyController.params.userId = "glen"def model = 0, model["itemNames"].size()}}
  37. 37.  approach for integration tests is different: tests are run against a live database, so you createdata via the domain classes as you do in the live application. But because youare working against a database, there are noguarantees that data will be returned in the orderyou expect
  38. 38.  When only an integration test will do: Grails’ unit test support will get you a long way inyour testing endeavors, but there are gaps in itscoverage you need to be aware of. In particular, it doesn’t give you any help witheither criteria or Hibernate Query Language (HQL)queries, nor does it have any support for testingURL mappings.
  39. 39.  Testing URL mappings is a simple matter ofleveraging the GrailsUrlMappings-TestCase supportclass: Let’s say, for the sake of argument, that we have thesemappings:class UrlMappings {static mappings = {"/basket/$username"(controller: "basket", action: "show")"/$controller/$action?/$id?"()"500"(view: "error")}}
  40. 40. class UrlMappingsTestCase extends grails.test.GrailsUrlMappingsTestCase {void testMappings() {assertUrlMapping("/item/edit/123",controller: "item",action: "edit") {id = 123}assertUrlMapping("/basket/fred",controller: "basket",action: "show") {username = "fred"}assertForwardUrlMapping(500, view: "error")}}
  41. 41.  loads all the application’s URL mappings and does all thenecessary preparation in setUp().themselves. The foot soldier of URL mapping tests is theassertUrlMapping() method B, which accepts a URL as thefirst argument, and a controller and action as named ones. In the first test, we make sure that the URL "/item/edit/123"maps to the item controller and edit action, with the value123 mapped to the id parameter.This method also checksthat the reversemapping works. There is also a corresponding assertReverseUrlMapping()method that accepts the same arguments as the otherassertion methods.
  42. 42.  Reloading Agent Grails 2.0 reloading mechanism no longer usesclass loaders, but instead uses a JVM agent toreload changes to class files.This results ingreatly improved reliability when reloadingchanges and also ensures that the class filesstored in disk remain consistent with the classfiles loaded in memory. which reduces the need to run the cleancommand.
  43. 43.  Clean Command Purpose: The clean command deletes all compiledresources from the application. Since Groovy is acompiled language, as with Java, this issometimes useful to clear old instances ofclasses and ensure correct compilation. Its also agood idea to run this script before running testsor creating aWAR file to ensure a fullcompilation occurs.
  44. 44.  Enhanced Error Reporting and Diagnosis Error reporting and problem diagnosis hasbeen greatly improved with a new errors viewthat analyses stack traces and recursivelydisplays problem areas in your code:
  45. 45.  Grails 2.0 now uses the H2 database insteadof HSQLDB, and enables the H2 databaseconsole in development mode (at the URI/dbconsole) to check the database
  46. 46.  Groovy 1.8 Grails 2.0 comes with Groovy 1.8
  47. 47.  Binary Plugins Grails plugins can now be packaged as JARfiles and published to standard mavenrepositories.This even works for GSP andstatic resources (with resources plugin 1.0.1).
  48. 48.  Controller Actions as Methods It is now possible to define controller actions asmethods instead of using closures as in previousversions of Grails. In fact this is now thepreferred way of expressing an action. Forexample: // action as a method def index() { } // action as a closure def index = { }
  49. 49.  Binding Primitive Method Action Arguments It is now possible to bind form parameters to action argumentswhere the name of the form element matches the argumentname. For example given the following form: <g:form name="myForm" action="save"> <input name="name" /> <input name="age" /> </g:form> You can define an action that declares arguments for each inputand automatically converts the parameters to the appropriate type: def save(String name, int age) { // remaining }
  50. 50.  Servlet 3.0 Async Features Grails now supports Servlet 3.0 including theAsynchronous programming model defined by thespecification: def index() { def ctx = startAsync() ctx.start { new Book(title:"The Stand").save() render template:"books", model:[books:Book.list()] ctx.complete() } }
  51. 51.  Link Generation API A general purpose LinkGenerator class is nowavailable. that is usable anywhere within a Grails applicationand not just within the context of a controller. Forexample if you need to generate links in a service oran asynchronous background job outside the scope ofa request: LinkGenerator grailsLinkGenerator def generateLink() {"book",action:"list") }
  52. 52.  Page RenderingAPI: Like the LinkGenerator the new PageRenderer can be used to renderGSP pages outside the scope of a web request, such as in a scheduled jobor web service.The PageRenderer class features a very similarAPI to therender method found within controllers: grails.gsp.PageRenderer groovyPageRenderer void welcomeUser(User user) { def contents =groovyPageRenderer.render(view:"/emails/welcomeLetter", model:[user: user]) sendEmail { to body contents } }
  53. 53.  The PageRenderer service also allows you topre-process GSPs into HTML templates: newFile("/path/to/welcome.html").withWriter { w-> groovyPageRenderer.renderTo(view:"/page/content", w) }
  54. 54.  Filter Exclusions Filters may now express controller, action and uri exclusions to offer moreoptions for expressing to which requests a particular filter should be applied. filter1(actionExclude: log*) { before = { // … } } filter2(controllerExclude: auth) { before = { // … } } filter3(uriExclude: /secure*) { before = { // … } }
  55. 55.  HTML5 Scaffolding There is a new HTML5-based scaffolding UI jQuery by Default
  56. 56.  Customizable URL Formats The default URL Mapping mechanism supports camel case namesin the URLs.The default URL for accessing an action namedaddNumbers in a controller named MathHelperController wouldbe something like /mathHelper/addNumbers. Grails allows forthe customization of this pattern and provides an implementationwhich replaces the camel case convention with a hyphenatedconvention that would support URLs like /math-helper/add-numbers.To enable hyphenated URLs assign a value of "hyphenated" to thegrails.web.url.converter property in grails-app/conf/Config.groovy. // grails-app/conf/Config.groovy grails.web.url.converter = hyphenated
  57. 57.  Detached Criteria and Where Queries Grails 2.0 features support forDetachedCriteria which are criteria queriesthat are not associated with any session orconnection and thus can be more easilyreused and composed.
  58. 58.  New findOrCreate and findOrSave Methods Domain classes have support for the findOrCreateWhere,findOrSaveWhere, findOrCreateBy and findOrSaveBy query methodswhich behave just like findWhere and findBy methods except that theyshould never return null. If a matching instance cannot be found in the database then a newinstance is created, populated with values represented in the queryparameters and returned. In the case of findOrSaveWhere andfindOrSaveBy, the instance is saved before being returned. def book = Book.findOrCreateWhere(author: Douglas Adams, title:"TheHitchikers GuideToThe Galaxy") def book = Book.findOrSaveWhere(author: Daniel Suarez, title:Daemon) def book = Book.findOrCreateByAuthorAndTitle(Daniel Suarez,Daemon) def book = Book.findOrSaveByAuthorAndTitle(Daniel Suarez,Daemon)
  59. 59.  Multiple Data Sources Support It is now possible to define multiple datasourcesin DataSource.groovy and declare one or more datasources a particular domain uses bydefault: class ZipCode { String code static mapping = { datasource ZIP_CODES } }
  60. 60.  development { dataSource { dbCreate = "create-drop" url = "jdbc:h2:mem:devDb" } dataSource_lookup { dialect = org.hibernate.dialect.MySQLInnoDBDialect driverClassName = com.mysql.jdbc.Driver username = lookup password = secret url = jdbc:mysql://localhost/lookup dbCreate = update } }
  61. 61.  Database Reverse Engineering A new database reverse engineering pluginhas been designed and built for Grails 2.0 thatallows you to generate a domain model froman existing database schema.
  62. 62.  Hibernate 3.6 Grails 2.0 is now built on Hibernate 3.6
  63. 63.  Grails Command Aliases The alias command may be used to definealiases for grails commands. The following command creates an aliasnamed rit (short for "run integration tests"): grails alias rit test-app integration:
  64. 64.  Cache Plugin Grails 2.1 installs the cache plugin by default.This plugin provides powerful and easy to usecache functionality to applications andplugins.
  65. 65.  New GORM Methods In Grails 2.1.1 domain classes now have staticmethods named first and last to retrieve the first and last instances from the datastore.See the first and last documentation fordetails.
  66. 66.  Namespace Support for plugins: Domain classes provided by a plugin will havetheir default database table name prefixedwith the plugin name if thegrails.gorm.table.prefix.enabled configproperty is set to true.
  67. 67.  For example, if the PublishingUtilities pluginprovides a domain class named Book, thedefault table name for that domain class willbe PUBLISHING_UTILITIES_BOOK if thegrails.gorm.table.prefix.enabled configproperty is set to true.
  68. 68.  URL Mappings may now include a plugin attribute to indicate that thecontroller referenced in the mapping is provided by a particularplugin. static mappings = { // requests to /bookAuthors will be handled by the // AuthorController provided by the BookUtilities plugin "/bookAuthors" { controller = author plugin = bookUtilities } // requests to /publishingAuthors will be handled by the // AuthorController provided by the Publishing plugin "/publishingAuthors" { controller = author plugin = publishing } }
  69. 69.  Controller methods and GSPTags whichaccept a controller name as a paramater nowsupport an optional parameter indicating thatthe controller is provided by a specific plugin. <g:link controller="user"plugin="springSecurity">ManageUsers</g:link>
  70. 70.  class DemoController { def index() { redirect controller: user, action: list, plugin:springSecurity } }
  71. 71.  ForkedTomcat Execution Grails 2.2 supports forked JVM execution of theTomcat container in development mode.Thishas several benefits including: • Reduced memory consumption, since theGrails build system can exit • Isolation of the build classpath from theruntime classpath •The ability to deploy other Grails/Springapplications in parallel without conflictingdependencies
  72. 72.  SQL Projections In Criteria Queries Grails 2.2 adds new functionality to criteriaqueries to provide access to Hibernates SQLprojection
  73. 73.  following scripts to see what plugins needed updating grails list-plugin-updates To update a plugin you just run install-plugin againand itll detect that the plugins already installed andwill remove the old one and install the new one. For asmall version delta this should be fine, but Id do themone at a time and test in-between (but do the 2JQuery plugins together). If youre lucky the plugin either has no compatibilityissues, or theyre documented in the plugin docs, sobe sure to check there before upgrading.
  74. 74.  From Grails 2.2 on, you should change theplugins section of BuildConfig.groovy. Afterthat you can run grails list-plugin-updatesagain and it will ask to update yourdependencies.