1 / 75

Grails Advanced

By- Saurabh Dixit. Grails Advanced. Agenda:. 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. Plugins :. Grails Plugins : Install Grails plugins Create a new plugin

doctor
Download Presentation

Grails Advanced

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. By- Saurabh Dixit Grails Advanced

  2. Agenda: • 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

  3. Plugins: • Grails Plugins: • Install Grails plugins • Create a new plugin • Use custom plugin in multiple applications

  4. Spring Security Plugin: • Installing Plugin • Install-plugin spring-security-core • Using s2-quick start

  5. 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' ]

  6. Static Resources: • 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 grails-app/conf/ApplicationResources.groovy.

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

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

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

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

  13. 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: • <imgsrc="${resource(dir:'images',file:'grails_logo.png')}" ... />

  14. Adding resources on the layout->main • <r:require modules=" bootstrap, bootstrapNavigation, validationEngine,maskedInput, smartPagination, jqueryTmpl, jqueryUi, jquery, toolTip " /> • <g:layoutHead /> • <r:layoutResources />

  15. Adding Layout file to view: • <g:applyLayout name="main" /> • In this way you need not to include resources on every view

  16. Web Services: • Web services are all about providing a web API onto your web application and are typically implemented in either • REST • or SOAP.

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

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

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

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

  21. Each HTTP method such as GET, PUT, POST and DELETE map to unique actions within the controller as outlined by the table below:

  22. 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"] }

  23. 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 non-browser clients is to use the XHTTP-Method-Override to specify the alternative method name.

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

  25. Firefox Poster Addon • 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.

  26. Testing: • 1. Unit testing: • 2. Functional Testing • 3. Integration Testing

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

  28. Useful assertions available to your test cases:

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

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

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

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

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

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

  35. 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 } ] } }

  36. 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() } }

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

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

  39. 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") } }

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

  42. Grails 2.0 • 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.

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

  44. 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:

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

  46. Groovy 1.8 • Grails 2.0 comes with Groovy 1.8

  47. 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).

  48. 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 = { • }

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

  50. 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() • } • }

More Related