Document

advertisement
By- Saurabh Dixit








Grails Plugins
Resources
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




Grails Plugins:
Install Grails plugins
Create a new plugin
Use custom plugin in multiple applications



Installing Plugin
Install-plugin spring-security-core
Using s2-quick start
Configuration in config file:
import
grails.plugins.springsecurity.SecurityConfigType;
 grails.plugins.springsecurity.securityConfigType =
SecurityConfigType.InterceptUrlMap


grails.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' ]



Including resources - using tags:
Declaring modules:
You can declare resource modules in both
applications and plugins. There are a couple of ways
of doing this, but the most common approach is to
add one or more dedicated artifacts to the project.
For an application this might be grailsapp/conf/ApplicationResources.groovy.





















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'
"core", "utils" and "forms" are the names of our
application modules.
 You can also see that the "utils" module depends on
"jquery“
 If we look a bit deeper into the above module
definitions, we can see that individual resources are
declared within a module using "resource" plus a
URL. This URL is the location of the resource relative
to the web-app directory in your project. If you wish,
you can also add extra attributes for fine-grained
control of resources, in particular via the
"disposition" setting.



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"



Including resources in a page
As you know, you previously had to declare
all your CSS and Javascript links explicitly in
your layouts and views.
So how does this change with the Resources
plugin? Instead of putting in links to
individual resources, you declare which
modules your page requires, which makes for
much conciser <head> blocks.

In addition, you specify where in the page the resource links
should go. Here's an example of a very simple layout using
Resources:
<html>
<head>
...
<r:require modules="common, jquery"/>
<r:layoutResources/>
</head>
<body>
...
<r:layoutResources/>
</body>
</html>



<r:require> tag tells Grails which static
resources to include in the page
<r:layoutResources> tags specify where the
links should go.
You should have two <r:layoutResources>
tags: one in <head> and the other in <body>.
Any resource with a disposition of "head" will
go where the first one is, while those with a
disposition of "defer" will be inserted at the
second's location.



Ad-hoc resources
The Resources plugin calls inline images and
scripts "ad-hoc resources". These typically
aren't declared in modules and are simply
processed as and when they are encountered
in the page. A standard inline image link looks
something like:
<img
src="${resource(dir:'images',file:'grails_logo.p
ng')}" ... />




Adding resources on the layout->main
<r:require modules=" bootstrap,
bootstrapNavigation,
validationEngine,maskedInput,
smartPagination, jqueryTmpl, jqueryUi, jquery,
toolTip " />
<g:layoutHead />
<r:layoutResources />



Adding Layout file to view:
<g:applyLayout name="main" />
In this way you need not to include resources
on every view

Web services are all about providing a web API onto your
web application and are typically implemented in either
 REST
 or SOAP.

REST:
 Using a RESTful solution
▪ The first step in creating an API for an application is
deciding what it should allow clients to do.
▪ After all, if a feature isn’t available in the API, a client
can’t use it.
▪ Working out what should go into the API isn’t always an
easy task, but during development you have scope to
experiment. Once the API is published, that’s it. You have
to avoid changes that will disrupt those software clients
that rely on it.
Adding elements to an API often causes fewer
problems than changing or removing existing
elements.
 A good strategy is to start minimally and grow the
API as required.
 REST is not really a technology in itself, but more an
architectural pattern.


REST is very simple and just involves using plain XML or
JSON as a communication medium, combined with URL
patterns that are "representational" of the underlying
system, and HTTP methods such as GET, PUT, POST
and 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 creating
data, POST for updating and so on. In this sense REST
fits quite well with CRUD.

URL patterns:
 The first step to implementing REST with Grails is
to provide RESTful URL mappings:
static mappings = {
"/product/$id?"(resource:"product")
}
 This maps the URI /product onto a
ProductController.

Each HTTP method such as GET, PUT, POST and
DELETE map to unique actions within the controller
as outlined by the table below:
Method
Action
GET
show
PUT
update
POST
save
DELETE
delete

You can alter how HTTP methods are handled by
using 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 used
previously, in this case Grails will not provide
automatic XML or JSON marshalling unless you
specify the parseRequest argument:
"/product/$id"(controller: "product", parseRequest: true) {
action = [GET: "show", PUT: "update", DELETE: "delete", POST: "save"]
}


Issuing a request with a method other than GET or
POST from a regular browser is not possible without
some help from Grails.
When defining a form you can specify an alternative
method 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 request's HTTP method.
Another alternative for changing the method for nonbrowser clients is to use the XHTTP-Method-Override to
specify the alternative method name.

XML Marshalling – Reading:
 The controller can use Grails' XML marshalling support to
implement the GET method:
import grails.converters.XML
class ProductController {
def show() {
if (params.id && Product.exists(params.id)) {
def p = Product.findByName(params.id)
render 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 we
get all products, otherwise if we go to /product/MacBook we only
get a MacBook.


Using firefox Poster addon:
Install poster plugin on the firefox, and then
find it on the tools tab, and then you will be
able to send http requests to your application
and test your rest API requests and
responses.



1. Unit testing:
2. Functional Testing
3. Integration Testing

Unit Testing:
 Why are we starting with unit tests?
 But as you’ll see later, you can also use Grails integration
tests for “unit testing” if you want.
 There are two primary advantages of unit tests over
integration tests:
▪ They’re quicker to run.
▪ You can run them from within your IDE.

Useful assertions available to your test cases:
assertEquals(expected, actual)
Compares two values or objects for equality using
the equals() method
assertTrue(value)
Checks that the given value is true after being
coerced to a Boolean
assertFalse(value)
Checks that the given value is false after being
coerced to a Boolean
assertNull(value)
Checks that the given value is null
assertNotNull(value)
Checks that the given value is not null
assertSame(expected, actual)
Checks that two objects are the same instance
assertArrayEquals(expected,
actual)
Compares two arrays for equality, checking that
they have exactly the same elements
shouldFail(type, closure)
Checks that the given closure throws an exception
of the given type, or any exception if type is omitted

Who are you mocking?
 The process of mocking involves providing fake
versions of classes or methods that can be used in
place of the real implementations.
 The cool thing is that you can control the behavior
of the mock object or method, so you can pass
known data to the object under test.
 Mocking can be used at any level of testing, but
it’s most commonly associated with unit tests.
Many of the methods provided by
GrailsUnitTestCase are used to mock the dynamic
properties and methods that would normally be
injected into classes by Grails.
 All of the mock*() methods provided by
GrailsUnitTestCase use metaclass programming to
add mock properties, methods, and objects. That
means you can add your own or override the
existing ones to fine-tune the behavior.



In addition, the mock validation performs real
Spring databinding, so the errors
property is a real instance of Spring’s Errors
interface. This allows you to check for
multiple constraint violations on a single
field.

Integration Testing:
 Where unit tests are about testing individual,
atomic units of functionality (like classes and their
methods), integration tests are designed to test
larger parts of an application, such as a controller
and its dependencies together.
 The main focus is on ensuring that the units work
together correctly—that they integrate properly.

In Grails, integration tests appear on the surface to be
unit tests. In fact, if you create a new integration test
with this command,
grails create-integration-test Book


The fundamental difference is that integration tests run
inside a full Grails environment, with a running database
and all those dynamic methods and properties that
you’re used to.
You don’t have to mock any of them. For all intents and
purposes, the tests run against a real instance of your
application.
The main thing missing is the servlet container, the
lack 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.
No Grails or servlet filters are executed.
URL mappings have no effect.
 Views can’t be tested.

Under the hood:
 Each integration test is run inside a transaction
that’s rolled back at the end of the test. This
means that no changes are committed to the
database. Also, the default Grails environment for
tests is “test”.
class MyController {
def myService
def show = {
def items = myService.fetchItemsFor(params.userId)
[ itemNames: items.collect { it.name } ]
}
}

what if the service method returns null instead?
There’s no reason it can’t do so, but now you can see
that the controller will throw a NullPointerException
because of the code items.collect {...}.
class MyControllerTests extends GroovyTestCase{
def myService
void testShowNoItems() {
def myController = new MyController()
myController.myService = myService
myController.params.userId = "glen"
def model = myController.show()
assertEquals 0, model["itemNames"].size()
}
}

approach for integration tests is different:
 tests are run against a live database, so you create
data via the domain classes
 as you do in the live application. But because you
are working against a database, there are no
guarantees that data will be returned in the order
you expect

When only an integration test will do:
 Grails’ unit test support will get you a long way in
your testing endeavors, but there are gaps in its
coverage you need to be aware of.
 In particular, it doesn’t give you any help with
either criteria or Hibernate Query Language (HQL)
queries, nor does it have any support for testing
URL mappings.

Testing URL mappings is a simple matter of
leveraging the GrailsUrlMappings- TestCase support
class:
 Let’s say, for the sake of argument, that we have these
mappings:
class UrlMappings {
static mappings = {
"/basket/$username"(controller: "basket", action: "show")
"/$controller/$action?/$id?"()
"500"(view: "error")
}
}
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")
}
}




loads all the application’s URL mappings and does all the
necessary preparation in setUp().themselves.
The foot soldier of URL mapping tests is the
assertUrlMapping() method B, which accepts a URL as the
first 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 value
123 mapped to the id parameter. This method also checks
that the reverse
mapping works.
There is also a corresponding assertReverseUrlMapping()
method that accepts the same arguments as the other
assertion methods.



Reloading Agent
Grails 2.0 reloading mechanism no longer uses
class loaders, but instead uses a JVM agent to
reload changes to class files. This results in
greatly improved reliability when reloading
changes and also ensures that the class files
stored in disk remain consistent with the class
files loaded in memory.
which reduces the need to run the clean
command.



Clean Command
Purpose:
The clean command deletes all compiled
resources from the application. Since Groovy is a
compiled language, as with Java, this is
sometimes useful to clear old instances of
classes and ensure correct compilation. It's also a
good idea to run this script before running tests
or creating a WAR file to ensure a full
compilation occurs.


Enhanced Error Reporting and Diagnosis
Error reporting and problem diagnosis has
been greatly improved with a new errors view
that analyses stack traces and recursively
displays problem areas in your code:

Grails 2.0 now uses the H2 database instead
of HSQLDB, and enables the H2 database
console in development mode (at the URI
/dbconsole) to check the database


Groovy 1.8
Grails 2.0 comes with Groovy 1.8


Binary Plugins
Grails plugins can now be packaged as JAR
files and published to standard maven
repositories. This even works for GSP and
static resources (with resources plugin 1.0.1).
Controller Actions as Methods
It is now possible to define controller actions as
methods instead of using closures as in previous
versions of Grails. In fact this is now the
preferred way of expressing an action. For
example:
 // action as a method
 def index() {
 }
 // action as a closure
 def index = {
 }













Binding Primitive Method Action Arguments
It is now possible to bind form parameters to action arguments
where the name of the form element matches the argument
name. 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 input
and automatically converts the
parameters to the appropriate type:
def save(String name, int age) {
// remaining
}










Servlet 3.0 Async Features
Grails now supports Servlet 3.0 including the
Asynchronous programming model defined by the
specification:
def index() {
def ctx = startAsync()
ctx.start {
new Book(title:"The Stand").save()
render template:"books", model:[books:Book.list()]
ctx.complete()
}
}







Link Generation API
A general purpose LinkGenerator class is now
available.
that is usable anywhere within a Grails application
and not just within the context of a controller. For
example if you need to generate links in a service or
an asynchronous background job outside the scope of
a request:
LinkGenerator grailsLinkGenerator
def generateLink() {
grailsLinkGenerator.link(controller:"book",
action:"list")
}


Page Rendering API:
Like the LinkGenerator the new PageRenderer can be used to render
GSP pages outside the scope of a web request, such as in a scheduled job
or web service. The PageRenderer class features a very similar API to the
render method found within controllers:

grails.gsp.PageRenderer groovyPageRenderer


void welcomeUser(User user) {
def contents =
groovyPageRenderer.render(view:"/emails/welcomeLetter",
model:[user: user])
sendEmail {
to user.email
body contents
}
}










The PageRenderer service also allows you to
pre-process GSPs into HTML templates:
new
File("/path/to/welcome.html").withWriter { w
->
groovyPageRenderer.renderTo(view:"/page/c
ontent", w)
}


Filter Exclusions
Filters may now express controller, action and uri exclusions to offer more
options for expressing to which requests a particular filter should be applied.















filter1(actionExclude: 'log*') {
before = {
// …
}
}
filter2(controllerExclude: 'auth') {
before = {
// …
}
}
filter3(uriExclude: '/secure*') {
before = {
// …
}
}



HTML5 Scaffolding
There is a new HTML5-based scaffolding UI
jQuery by Default
Customizable URL Formats
The default URL Mapping mechanism supports camel case names
in the URLs. The default URL for accessing an action named
addNumbers in a controller named MathHelperController would
be something like /mathHelper/addNumbers. Grails allows for
the customization of this pattern and provides an implementation
which replaces the camel case convention with a hyphenated
convention that would support URLs like /math-helper/addnumbers. To
 enable hyphenated URLs assign a value of "hyphenated" to the
grails.web.url.converter
 property in grails-app/conf/Config.groovy.



// grails-app/conf/Config.groovy

grails.web.url.converter = 'hyphenated'


Detached Criteria and Where Queries
Grails 2.0 features support for
DetachedCriteria which are criteria queries
that are not associated with any session or
connection and thus can be more easily
reused and composed.







New findOrCreate and findOrSave Methods
Domain classes have support for the findOrCreateWhere,
findOrSaveWhere, findOrCreateBy and findOrSaveBy query methods
which behave just like findWhere and findBy methods except that they
should never return null.
If a matching instance cannot be found in the database then a new
instance is created, populated with values represented in the query
parameters and returned. In the case of findOrSaveWhere and
findOrSaveBy, the instance is saved before being returned.
def book = Book.findOrCreateWhere(author: 'Douglas Adams', title:
"TheHitchiker's Guide To The Galaxy")
def book = Book.findOrSaveWhere(author: 'Daniel Suarez', title:
'Daemon')
def book = Book.findOrCreateByAuthorAndTitle('Daniel Suarez',
'Daemon')
def book = Book.findOrSaveByAuthorAndTitle('Daniel Suarez',
'Daemon')
Multiple Data Sources Support
It is now possible to define multiple datasources
in DataSource.groovy and declare one or
 more datasources a particular domain uses by
default:
 class ZipCode {
 String code
 static mapping = {
 datasource 'ZIP_CODES'
 }
 }
















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'
}
}


Database Reverse Engineering
A new database reverse engineering plugin
has been designed and built for Grails 2.0 that
allows you to generate a domain model from
an existing database schema.


Hibernate 3.6
Grails 2.0 is now built on Hibernate 3.6




Grails Command Aliases
The alias command may be used to define
aliases for grails commands.
The following command creates an alias
named rit (short for "run integration tests"):
grails alias rit test-app integration:


Cache Plugin
Grails 2.1 installs the cache plugin by default.
This plugin provides powerful and easy to use
cache functionality to applications and
plugins.



New GORM Methods
In Grails 2.1.1 domain classes now have static
methods named first and last to retrieve the
first and last instances from the datastore.
See the first and last documentation for
details.


Namespace Support for plugins:
Domain classes provided by a plugin will have
their default database table name prefixed
with the plugin name if the
grails.gorm.table.prefix.enabled config
property is set to true.

For example, if the PublishingUtilities plugin
provides a domain class named Book, the
default table name for that domain class will
be PUBLISHING_UTILITIES_BOOK if the
grails.gorm.table.prefix.enabled config
property is set to true.















URL Mappings may now include a plugin attribute to indicate that the
controller referenced in the mapping is provided by a particular
plugin.
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'
}
}


Controller methods and GSP Tags which
accept a controller name as a paramater now
support an optional parameter indicating that
the controller is provided by a specific plugin.
<g:link controller="user"
plugin="springSecurity">Manage
Users</g:link>





class DemoController {
def index() {
redirect controller: 'user', action: 'list', plugin:
'springSecurity'
}
}
Forked Tomcat Execution
Grails 2.2 supports forked JVM execution of the
Tomcat container in development mode. This
has several benefits including:
 • Reduced memory consumption, since the
Grails build system can exit
 • Isolation of the build classpath from the
runtime classpath
 • The ability to deploy other Grails/Spring
applications in parallel without conflicting
dependencies




SQL Projections In Criteria Queries
Grails 2.2 adds new functionality to criteria
queries to provide access to Hibernate's SQL
projection
following scripts to see what plugins needed updating
grails list-plugin-updates
To update a plugin you just run install-plugin again
and it'll detect that the plugin's already installed and
will remove the old one and install the new one. For a
small version delta this should be fine, but I'd do them
one at a time and test in-between (but do the 2
JQuery plugins together).
 If you're lucky the plugin either has no compatibility
issues, or they're documented in the plugin docs, so
be sure to check there before upgrading.




From Grails 2.2 on, you should change the
plugins section of BuildConfig.groovy. After
that you can run grails list-plugin-updates
again and it will ask to update your
dependencies.
Download