Viewing category: Book Review
![]() ![]() Friday, 4 September 2009
![]() Book - Grails 1.1 Web Application Development - Part 13
![]() Chapter 12 - Searching, RSS, and REST Services
This chapter, as the title states, covers the implementation of Search, RSS and REST Services. I must digress a bit first. After implementing the search capability, I tested the capability manually and uncovered a bug. Because I wanted to see the search results pull back both Message and File objects, and I wasn't uploading File objects in BootStrap.groovy, I posted a new file and tagged it with two existing tags and one new tag. When doing so, I inadvertently entered two consecutive space delimiters into the tag list I keyed. This caused the dreaded exception org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value: tagging.Tagger.tag. Not realizing I was entering two consecutive delimiters, I found this odd since I could enter all new tags,or reuse only existing tags without an issue. After digging around a bit, I narrowed the issue to the createTagRelationships method in class TagService. The fix turned out to be incredibly simple, thanks to Groovy. The problem is that the author used the Java version of the split method on the tag string. Java will render consecutive delimiters as instances of an empty String. Groovy simply discards those instances. Thus, changing the line: return spaceDelimitedTags?.split(' ')?.collect { tagName ->to: return spaceDelimitedTags?.split()?.collect { tagName ->solves the problem. We use the Searchable plugin to implement the functionality. Searchable is built on top of Lucene and the Compass Search Engine framework we are told. Using Searchable makes this implementation fairly trivial. To make the domains searchable, in this case the Message and File domains, we need to add the searchable property as: static searchable = trueThe application can now be started and we can navigate to http://localhost:8080/teamwork/searchable and start searching! Could it be any simpler? The plugin has provided a controller making this possible. From a user standpoint, we need to better integrate the search function into our application. The remainder of this section of the chapter is devoted to doing just that. We create our own controller that uses the SearchableService also provided by the plug-in. The searchResult returned from the call to the search method on searchableService contains several properties. These are listed and explained by the author. Next up is the implementation of an RSS feed. We are told that there is plug-in just for this purpose called Feeds and is built on the ROME API. Considering how plug-ins have simplified our lives several times while building the app, it is somewhat surprising that Jon states our needs are simple and we will roll our own. The reason given for this is to provide an opportunity to become more familiar with Groovy builders. Before we begin building our feed, Jon gives us an apt warning about building XML within the controller class. The two reasons for this are:
Finally we get to implementing REST services. SOAP support is available in Grails through a couple plug-ins, XFire or Axis2, we are told. We are given a brief overview of REST before diving in deeper, as well as an explanation of how Grails manages URL mapping. We need to add URL mappings to properly respond to the HTTP method. There are several types of mappings and each are explained reasonably well. We learn, too, that constraints can be applied to mappings and an example is provided. Jon lets us know that there is more to mapping and gives us a link to the documentation. After all this information is given, we are shown just how to update our UrlMappings.groovy class. From there we create our controllers where we are exposed to Grails converters. These are convenience mechanisms that make returning an XML response from our domain objects elementary. The following illustrates how simple it is to generate XML from a domain object using a converter: render Message.get(params.id)as XMLJon appropriately warns us about using converter when providing interfaces for clients since property changes to the domain will cause a change to the interface. After we complete the build of the controller, we set up authentication for the REST actions. We simply require the client to pass the username and password in the header of the request. Unfortunately, Grails does not inject services into a filter, however the Spring application context is available as a property. This allows to access the security manager service. With the changes to the filter, all of the functional changes have been made. In order to test it, we create a script called RestTest.groovy in the scripts folder located in the project home directory. There were some minor problems here when comparing this to the downloaded source code. First, the file was called by a different name. Secondly, and most important, he uses the PUT method rather than the POST method in the book in method createMessage. Lastly, but unimportantly, in the downloaded source the httpConnection variable is statically rather than dynamically typed. In this chapter we learned a few more useful tidbits about Grails and developed functionality that many of us will be called upon to do ourselves. As demonstrated by this chapter, and as we continually learn, Grails makes it easy. Part 1 of this series can be seen here. Part 2 of this series can be seen here. Part 3 of this series can be seen here. Part 4 of this series can be seen here. Part 5 of this series can be seen here. Part 6 of this series can be seen here. Part 7 of this series can be seen here. Part 8 of this series can be seen here. Part 9 of this series can be seen here. Part 10 of this series can be seen here. Part 11 of this series can be seen here. Part 12 of this series can be seen here. ![]()
Rate this article
Read more | 0 comments ![]()
Posted by Bill Turner
at 12:11 PM
![]() Link directly to this article.
![]() ![]() Thursday, 27 August 2009
![]() Book - Grails 1.1 Web Application Development - Part 12
![]() Chapter 11 - AJAX and RIA Frameworks
With Grails built-in support for AJAX and the power supplied by the RichUI plugin, we are able to take the tagging framework implemented in the previous chapter to new heights. We add in-line editing of our tags, auto completion and a tag cloud. The chapter begins with adding in-line editing. We learn that Grails uses the Prototype framework for the AJAX support. We are given an overview of the remoteLink and formRemote tags, including a table describing the attributes. After a discussion of the user actions and the controller actions that will be needed to handle those actions, we create a TaggableController implementing the requisite actions. We then move on to add a couple in-line forms that will be used to render the edit and show tags views. Next we make slight modifications to the _message.gsp and _file.gsp templates. Finally, we are instructed to add the prototype library to the main template. This was quick and simple. From there we move on to the addition of auto-complete capabilities to our tag lookup, creation and editing. The author tells us that there are two plugins available: GrailsUI and RichUI. They both wrap the YUI auto-complete widget. Jon chooses to use the RichUI plug-in as it has more features than the GrailsUI plug-in and the default styling is more appropriate for the application. After installing the plug-in, we add two methods to the TaggableController: suggestTags and renderAsXml. The latter method is the more interesting of the two. It uses the render method, but instead of specifying a view or a template, a closure is specified. The closure is executed against the Groovy MarkupBuilder. Since this is a little difficult to conceptualize, Jon provides a concrete example. This is good, but, personally, I would have preferred to see it as a test or an assert at a minimum. Asserts are a great way to explore the language. At this point, we are introduced to two new tags provided by the autoComplete widget: resource:autoComplete and richUI:autoComplete. This is followed by a table describing the attributes available to the autoComplete tag. With this new found knowledge, we update the message create.gsp, the taggable editTagsForm template, the profile myTags view with the richUI:autoComplete tag. We are then directed to add the resource:autoComplete tag to the main layout head element. The author suggests booting up the application and testing the auto-complete feature at this point. Sure enough, it all works as desired. Now we are able to add tag clouds. We get a brief discussion of just what a tag cloud is and a sample based upon the words contained in the chapter. We are also given reasons why adding a tag cloud makes sense. Again, we use capabilities provided by the RichUI plug-in. We are presented with a static example from the online plug-in documentation and are encouraged to place it into one of our pages and then view the page. As you would expect, we get a nice little cloud. This is made possible through the richUI:tagCloud tag. We are also provided a table describing the attributes for the tag. Most of the work involved in implementing the tag cloud comes in areas other than the actual rendering of it. We add method cloudData to the TagService class. We then update the MessageController by injecting tagService and contentService, modifying the list method, and adding a filterByTag method. The FileController is similarly modified, however there is a trick to list method. Here we use listDistinct method on the CriteriaBuilder. This is necessary, we are told, because Hibernate uses an outer join to perform eager featches on multiple cardinality relationships. Finally, we get to changing the message and file list views. These are simply the aforementioned richUI:tagCloud added to a div element. And, Presto! We have a tag cloud! This chapter went very smoothly. There was only one small issue I found and was irrelevant. The chapter clearly demonstrates the power of plugins to make very user friendly interfaces. Part 1 of this series can be seen here. Part 2 of this series can be seen here. Part 3 of this series can be seen here. Part 4 of this series can be seen here. Part 5 of this series can be seen here. Part 6 of this series can be seen here. Part 7 of this series can be seen here. Part 8 of this series can be seen here. Part 9 of this series can be seen here. Part 10 of this series can be seen here. Part 11 of this series can be seen here. ![]()
Rate this article
Read more | 0 comments ![]()
Posted by Bill Turner
at 07:03 AM
![]() Link directly to this article.
![]() ![]() Sunday, 16 August 2009
![]() Book - Grails 1.1 Web Application Development - Part 11
![]() Chapter 10 - Managing Content through Tagging
This chapter continues building the application by adding tagging capabilities. Achieving this requires that we learn how to work with inheritance in domain classes, understand the available GORM persistence strategies, and gain insight into polymorphic queries over domain inheritance hierarchies. We also need to use manage collections using collect and sort to get the behavior we want. Initially we are given an overview of just what tagging is, and quickly move to a domain model needed to support tagging. After creating the initial model of Tag and Tagger, we create TagService. This provides methods for adding tags and is where we use the collect method. We are also shown the Elvis operator. A bit of trivia explains that the name for this operator comes from the fact that it looks Elvis' hair style. The author then has us write some integration tests to verify that all is working properly. We are required to implement further functionality in the Message class to make the tests pass. After making changes and having the tests pass successfully, we turn our attention to tagging File classes. Here is where we learn GORM supports two of the several Hibernate inheritance persistence strategies, table-per-hierarchy and table-per-subclass. The former creates one table per hierarchy and is the Grails default. The latter creates one table for each class in the hierarchy. Table-per-hierarchy has a drawback; a number of columns will have to be nullable. To override the default behavior, we are told to add the mapping property to the parent domain as follows: static mapping = { tablePerHierarchy false }In order to implement tagging File objects, we re-examine the domain model and add a superclass to Message and File called Taggable. We then add another test and quickly discover that our tests fail. This is due to the fact that the polymorphic nature of our queries returns all Message and File objects with the given tag even though we think we are querying objects of the specific type. This is remedied by adding another method on the Taggable class, and adding nearly identical methods to Message and File that override the finder method on Taggable. Once the domain and persistence logic is coded and tested, we move on to modifying the user interface. Jon discusses templating in Grails. In Grails, a template is the same as a GSP except that it is prefixed with and underscore. He shows the various ways templates are rendered and provides a warning regarding rendering a collection via the template. He states that we must be careful to pass in the actual collection by using the ${} notation. As we closeout the chapter, we create another service, ContentService and make greater use of templating. The added templating allows either Message or File posts to be displayed interchangeably. These final touches allow us to create a homepage wherein the user can specify which tags are of interest. The view will display the five most recent updates, either messages or files, and the five most recent items of interest, again, either messages or files. Throughout this chapter, there were few problems. In a few tests a user variable named fred is used that was not defined elsewhere, nor is the variable used in the book source. Again, as he has done in previous chapters, he references a view named post where none exists. And, he continues to unnecessarily use some optional things such as the access modifier public. These are all rather trivial issues. Part 1 of this series can be seen here. Part 2 of this series can be seen here. Part 3 of this series can be seen here. Part 4 of this series can be seen here. Part 5 of this series can be seen here. Part 6 of this series can be seen here. Part 7 of this series can be seen here. Part 8 of this series can be seen here. Part 9 of this series can be seen here. Part 10 of this series can be seen here. ![]()
Rate this article
Read more | 0 comments ![]()
Posted by Bill Turner
at 08:39 PM
![]() Link directly to this article.
![]() ![]() Monday, 10 August 2009
![]() Book - Grails 1.1 Web Application Development - Part 10
![]() Chapter 9 - Services
Grails provides a service layer to applications. Chapter 9 discusses the concept of services and through them, how to simplify our application. In this chapter we move logic out of the File controller and moving it into a service class, FileService. Doing so separates responsibility nicely, always an admirable goal. Thus, this chapter is essentially a refactoring. Even though the chapter is short and simple, we do learn a few new things. The first thing we learn is that services, through Grails, use Spring's declarative transactions making service methods transactional. This can be turned off by changing the value of the transactional property to false. The property is included and set to true in the stub created by the create-service command. The next thing we are introduced to is how Spring's dependency injection mechanism is implemented by Grails. We are told dependency injection is important in that it forces us to write code to the interface and not have to be concerned about how classes are constructed. Traditionally this is set up via configuration files. Of course, Grails uses convention over configuration. We are told that by following a few simple rules, which are presented, we can simply add a property to the class in which we want to add the class. For instance, to inject the file service we are creating, we simply need to add the line: def fileService An added benefit to loosely typing the service is that there is no need to restart the application after changes to the service when in development mode. The final significant thing we learn about services in this chapter is about the scope of services. By default services are created as singletons. This does mean that services using the default implementation are not thread-safe. The scope of the service can be overridden by defining a scope variable in the service and specifying one of a number of available scopes, which the author has listed and explained. To specify that a service to live within the request scope, all you need do is add the following line: static scope = 'request' The remainder of the chapter is dedicated to refactoring and creating the service. This all goes fairly smoothly. The issue I uncovered in the previous chapter regarding the inability to display some error messages are corrected. The changes I put into the create view, being irrelevant, were backed out by me and we are now in sync regarding that bit of code. The line specifying that view post be rendered still exists incorrectly. There is never any discussion of moving the method extractExtension from the controller to the service, though this should be relatively obvious from the listing of the service. Likewise, we are not told to remove the property injecting the user service into the controller, at least it is not clear that it should be done. This is a very minor issue, however, and failing to do so should not affect the application. Part 1 of this series can be seen here. Part 2 of this series can be seen here. Part 3 of this series can be seen here. Part 4 of this series can be seen here. Part 5 of this series can be seen here. Part 6 of this series can be seen here. Part 7 of this series can be seen here. Part 8 of this series can be seen here. Part 9 of this series can be seen here. ![]()
Rate this article
Read more | 0 comments ![]()
Posted by Bill Turner
at 12:26 PM
![]() Link directly to this article.
![]() ![]() Friday, 31 July 2009
![]() Book - Grails 1.1 Web Application Development - Part 9
![]() Chapter 8 - More GORM and Criteria
Part 1 of this series can be seen here. Part 2 of this series can be seen here. Part 3 of this series can be seen here. Part 4 of this series can be seen here. Part 5 of this series can be seen here. Part 6 of this series can be seen here. Part 7 of this series can be seen here. Part 8 of this series can be seen here. Chapter 8 builds upon our application by adding file versioning capability to our file sharing system. This provides the excuse to revisit GORM and criteria queries as promised in an earlier chapter. As we start the chapter, file sharing is modeled through two domains, File and FileData in a 1:1 relationship. Here we add FileVersion. FileVersion takes on all the responsibilities that File had, while File creates a hasMany property for the versions. In order to achieve the capability of retrieving the versions in the desired order, the author added a SortedSet property using the same name as the container specified in the hasMany map for the versions. In order to allow this ordering, FileVersion had to implement the Comparable interface and a compareTo method. Jon used the public access modifier on the compareTo method, which is unnecessary in Grails. It was nice having implementation of an ordered relationship between the two domains. After the requisite changes and additions were made, File is 1:m to FileVersion, and FileVersion is 1:1 to FileData. With this change, it became necessary to change how data was retrieved on the home page. This lead to the discussion of criteria queries. The first thing the author did was to show three dynamic queries from chapter 5 and the equivalent versions written using criteria. This clearly demonstrated how criteria queries are built. He then explains that nodes within the criteria can be used to specify logical operators and to query across associations. For the latter, a property added to File meant to hold a reference to the current FileVersion was used in demonstration. He also discussed the use of FetchMode as we still want to retrieve the User eagerly from the current version. After providing two tables, one a criteria reference, the other a listing of logical criteria operators, we are shown the use of criteria properties, in this case, limiting the results of our File query to ten. He closes the discussion of criteria queries by providing links to the Hibernate Criteria Javadoc, and informing us of and providing links to documentation on Projections and Scrollable Results. At this point, we are directed to modify the save method in the FileController. Here we run into a problem. The code listing on page 160 meant to display the errors does not work. In the listing, a view of post is referenced. No post view has been created thus far, nor is it contained in the downloaded source. The downloaded source references create as expected. Worse, though, is that by changing the model here from file to currentVersion breaks causes no messages to be displayed on an upload error. The problem is that the save is done on the File object and the Error object is bound to that, not to currentVersion. There are multiple solutions to this. One possible solution is to add a line just before the render to set the current version error object to the file error object. This is shown below. if (file.save()) { However, this smells to me. Rather, the preferred change in my opinion is to the create.gsp. Here the code currently reads: < g:hasErrors bean="${file}" > Change this to: < g:hasErrors > After writing the rather complex save logic in the controller, Jon tells us that he understands it is complex and difficult to test. He states that we will be moving much of this logic to a service in the chapter. The chapter is closes with the required changes to our home page and message properties, and by updating the download method in the FileController. I have to admit to being a bit frustrated by the errors encountered, though most books do seem to have some problems. None encountered so far have been insurmountable to me, but a noob may be really dazed and confused. Then again, problem solving is a great way to learn. If you feel that way, I suggest you download the free version of Jason Rudolph's mini-book Getting Started with Grails available at InfoQ, which was based on very early version of Grails and Groovy. ![]()
Rate this article
Read more | 0 comments ![]()
Posted by Bill Turner
at 08:53 PM
![]() Link directly to this article.
![]() ![]() Wednesday, 29 July 2009
![]() Book - Grails 1.1 Web Application Development - Part 8
![]() Chapter 7 - File Sharing
Part 1 of this series can be seen here. Part 2 of this series can be seen here. Part 3 of this series can be seen here. Part 4 of this series can be seen here. Part 5 of this series can be seen here. Part 6 of this series can be seen here. Part 7 of this series can be seen here. This chapter is quite short, as are the next two. A welcome respite after the more intense topics of earlier chapters. More than anything else, this chapter is really about adding functionality to the application we are building, adding the ability to upload and download files. With Grails providing access to Spring's MultipartFile interface, this is all very simple, just as so much else is easy when using Groovy and Grails. To accomplish these tasks, we create a File domain, controller, and create.gsp. We are told that the maxSize constraint provides a hint to GORM when generating the database schema. We are later reminded that relationships between domain objects use lazy instantiation by default. Thus, we create another domain called FileData that enjoys a one-to-one relationship with the File domain and is used exclusively for holding the contents of the file. This, we are assured, increases efficiency because when we load a list of files we will not be loading all the binary data associated with each file until requested. I am not sure if at this point this is the first time we are exposed to the belongsTo property. I have done enough Grails development that this is just trivia to me. Assuming it is the first time because a point was made of it, we learn that this is used to signify cascading operations between objects, i.e. when File is saved or deleted, the same operation is applied to FileData, which has implemented the belongsTo method. There were a couple more problems in this chapter, as well. I'll deal with the more minor first. In the section wherein we are putting in the logic for downloading files, we are given directions for updating the FileController. As is, it will not work quite properly in Firefox (on Windows, anyway) when downloading files with embedded spaces in their names. The fix is quite simple. Here is the line as specified on page 149: response.setHeader("Content-Disposition", "attachment; filename=${file.downloadName}") Changing this to: response.setHeader("Content-Disposition", /attachment; filename="${file.downloadName}"/) will assure that the proper file name is used. Here I used Groovy's slashy strings and surrounded the filename in double quotes. This fix was tested not only in Firefox, but also IE, Google Chrome, Opera and Safari, all on Windows XP. The second problem is more troubling, not so much that the mistake was made, but what it is I discovered along the way. When we are directed to update the home page, we are told to add code after the message div. There is no div in anything we've coded to this point that uses an id of message, nor a class of the same name. Now, looking at the code, it was fairly obvious to me what changes needed to be made to the section of code we were not directed to update based upon the code we were told to add. Essentially, this amounted to adding a div with a class of panel, plus a few other minor changes. However, to be sure I wasn't doing anything wrong, I felt it best to go back to the publisher site and check the errata. Here is what troubles me the most. The errata still has not been changed to include my submission from some weeks back. The only existing erratum is a fairly trivial syntax issue, not a code issue (or explanation thereof)as I had previously submitted. Is this an indication that the publisher wants to deny that there are any issues with the book? Or, are they just extremely slow with updating the errata? In either case, it is bad. Anyway, I downloaded the source code for the book. The source code from the previous chapters confirmed my theory that I had not failed to code properly, which agreed with a review of the previous chapters. It is just plain wrong. I will be submitting this to the publisher. We'll see what good that does. ![]()
Rate this article
Read more | 0 comments ![]()
Posted by Bill Turner
at 04:02 PM
![]() Link directly to this article.
![]() ![]() Thursday, 23 July 2009
![]() Book - Grails 1.1 Web Application Development - Part 7
![]() Chapter 6 - Testing
Part 1 of this series can be seen here. Part 2 of this series can be seen here. Part 3 of this series can be seen here. Part 4 of this series can be seen here. Part 5 of this series can be seen here. Part 6 of this series can be seen here. There are many plugins available to the Grails developer. Among them are: Easyb Testing, though new to it, a personal favorite of mine (the plugin does not appear to be ready, yet, there is little info on the plugin page. You can still use it. See the official easyb site.), Build Test Data, Selenium, Test Code Coverage, Canoo WebTest, CodeNarc and many others. While it would have been nice to have a more comprehensive chapter on testing, giving those listed above their proper due would get lengthy, perhaps worthy of a book of their own. The author instead focuses on unit testing, including many of the built-in mocking features, integration testing and functional testing using Functional Testing. The chapter starts off with a bit of history behind automated unit testing, its relationship to Extreme Programming (XP) and Test Driven Development (TDD). He explains how the original unit testing framework is JUnit and that Groovy comes with this, extending and enhancing it, and that the JUnit framework on which Groovy and Grails builds uses the conventions prior to JUnit 4 (meaning before annotations were available). I won't go into detail here. However, I do want to point out that he remarks on one of the best practices of using descriptive test names. Here is a place where I feel easyb, a Behavior Driven Development (BDD) framework, is far superior. I have another quibble, as well, in this section. He speaks of how many developers write test cases that do not execute against their application code, implying, I believe, that not only do you have to write tests that exercise the production code, but also that the tests must actually be meaningful. I will return to this later. My problem with this section, though, is that he gives an example of a bad test and does not demonstrate what a good test should look like. Someone likely to write a bad test, in my opinion, may not really understand what is wrong with the test as written and not intuit the proper way to write it. And, this brings up yet another quibble. Here, again, Jon seems to have chosen to roll his own rather than using the automated features included with Grails. Maybe the way test cases were generated changed during the writing of the book explaining the differences between the code he has here in this and other examples. That could explain it, but I think that this should have been revisited and updated with the 1.1 Grails release. I'd like to hear Jon comment on this. The changes are not dramatic, though. The name of the generated unit test for class User, for example, would read UserTests rather than UserUnitTests. Similarly, he extends GroovyTestCase, at least in the example on page 116 and others, rather than GrailsUnitTestCase. In other examples, he does extend GrailsUnitTestCase. In the example testing the MessageController, the framework generates a class that extends ControllerUnitTestCase and he uses GrailsUnitTestCase. The auto-genned classes, too, come with stubs for the setUp and tearDown methods, something not included in his examples. Jon does list the JUnit assert methods and the additional assert methods provided by the GroovyTestCase, from which GrailsUnitTestCase inherits. These additional assert methods are: assertArrayEquals, AssertContains, assertLength, assertScript, and assertToString. Also included are the convenience methods shouldFail and shouldFailWithCause. These shouldFail methods are then explained further with an example. These are a bit tricky. They take a closure and the closure is expected to throw an exception. If one is not thrown, the test fails. By using the WithCause variation, you can specify the exact type of exception you do expect. Any other exception or no exception at all will cause the test to fail. On page 121, the author tells us of the convention of where tests are expected to live, and explains that the tests are automatically generated when you use one of the create commands. He then goes on to write his own variation, as stated before, and inexplicably in my opinion. The example here is missing the import for GrailsUnitTestCase. I am not sure that the test was tested! We are then instructed on how to run the test case and the reporting explained. Nothing here should surprise the professional developer, especially one that has used one of the xUnit frameworks before. Next, Jon goes on to tell us of the problems we'll quickly encounter with testing a Grails app. Unit tests do not run within the Grails container. This means that dynamic methods and properties are not available to the unit test. This leads to a couple solutions, neither of which is ideal, mocking and running the tests as integration tests. Luckily, as Jon explains, mocking support is built-in through the GrailsUnitTestCase class. He provides a table showing the various methods supporting mocking and a brief description regarding their use: mockController, mockDomain, mockForConstraintsTests, mockFor, mockLogging, mockTagLib and registerMetaClass. Of these, he demonstrates the use of mockController, mockDomain, mockForConstraintsTests, and mockFor. He goes in depth on the latter to explain how the delegate property is used on the closure. When discussing mockForConstraintsTests the author seemingly violates his earlier assertion that you should write meaningful tests that I mentioned above. I find this rather ironic. Here he tests a constraint (page 127), but to validate only writes: assertTrue(message.hasErrors()) Well, this means that no matter what error is thrown, the test will pass. Wholly inadequate, in my opinion. It would be better, in my opinion, to take greater advantage of the error property. For example, the test in question could be written as: assertTrue message.errors.allErrors[0].toString().contains("Field error in object 'app.Message' on field 'title': rejected value []") The first line above could be used instead of the latter three, though takes a bit more work to figure out. You may need to run a test outputting the actual error string. Certainly, your test could get more sophisticated than this and there are other alternatives. All three tests in this example are similarly challenged and the solutions for testing reliably will vary. After explaining mocking, we are told of the limitations of unit testing, and Jon goes on to discuss integration testing. This is all fairly familiar territory so will not be discussed in depth. He does introduce us to grails.util.Environment in this section, something he promises to delve into deeper in a later chapter. I don't really agree with the reason he is using it, however. He is manipulating the creation of data in our BootStrap.groovy for testing reasons. It is my opinion that the test case should neither depend on the existence or non-existence of such data. Test cases should manage all the variables that impact proper execution. Finally, we get to functional testing and the Functional Testing plug-in. This is all so simple to install, create and implement, that it almost seems trivial. Just what we developers need! He does stress the trade-off necessary between the level of code coverage and the time it takes functional tests to run. The functional tests are run within the Grails container. While totally gratuitous on my part, a short discussion of the differences between Webtest and Functional Testing plugins is probably relevant. Webtest had been the original "go to" plugin for functional testing. The Functional Testing plugin seems to be the new favorite. Since many will undoubtedly work on legacy applications that use the former, understanding the differences could be necessary. There is a page on the Grails site that does discuss this, but is rather incomplete. Oh, well. ![]()
Rate this article
Read more | 2 comments ![]()
Posted by Bill Turner
at 04:21 PM
![]() Link directly to this article.
![]() ![]() Wednesday, 15 July 2009
![]() Book - Grails 1.1 Web Application Development - Part 6
![]() Chapter 5 - Authentication with JSecurity Plug-in
Part 1 of this series can be seen here. Part 2 of this series can be seen here. Part 3 of this series can be seen here. Part 4 of this series can be seen here. Part 5 of this series can be seen here. Many applications require security. Luckily, through Grails plug-in architecture and a number of available plug-ins devoted to the task, adding security a Grails application is relatively easy. In this chapter, Jon takes us through implementation of many normally encountered requirements using the JSecurity plug-in. I have only used the Spring Security (Acegi) plug-in prior to this, so I really looked forward to the experience (I have read about JSecurity and CAS previously). My impression after this chapter is that implementing JSecurity via the plug-in is a fairly simple process and is one I'll strongly consider on future projects. The only caveat to this is the same complaint I've had of features the book covered earlier, namely the decision to "roll your own" rather than using the supplied commands to create artifacts and teaching and modifying those. In the end, I am not sure what it is I don't know and will be forced into digging into the features of the plug-in before I use it. Certainly, this being a tutorial, a few additional pages covering the plug-in in greater detail does not seem unwarranted. The chapter starts off introducing us to the fact that there is a plug-in mechanism and tells us of several of the many areas for which plug-ins have been written. Jon explains that plug-ins can generate a number of artifacts, from classes to static resources, and can take part in build and runtime events. Further, he states that the core features of Grails are implemented as plug-ins, thus making the plug-in architecture fundamental to Grails, and provides the sample of GORM as a core plug-in, the plug-in used to abstract Hibernate. It seems that the reason JSecurity was used in the project is the ease with which it could be integrated with the existing domain model. This proved to be true, in my opinion. Jon explained that plug-ins are installed in a default directory, your user account. He then states that this gives rise to a number problems and provides two:
He went on to explain more about the structure of plug-ins, which is certainly nice to know information. He then tells us of the scripts the JSecurity plug-in makes available to the developer. However, we are then told that one will not be used because the default domain model generated is more complicated than the simple model used by the application. We do eventually use the CreateAuthController script to generate the login action and page. We are then provided a quick overview of JSecurity, covering the role, permissions, subject, principal and realm concepts. Permissions are not used in the application. Realms are delved in more deeply than the other subjects, and then we go on to creating our own realm. There are a couple scripts supplied by JSecurity for creating realms, CreateDbRealm and CreateLdapRealm, that are not used. What these create should be self evident from their names. Next, we go on to implementing the authenticate method in the realm. This gives rise to a discussion of dynamic finders. This is covered relatively sufficiently. Explaining how the term dynamic is derived from dynamically constructed method names rather than the fact that the methods are added to the domains dynamically, he covers all the operators that can be used when constructing a name. He rightly implies that the junction operators And and Or are limited to two conditions. This could easily be missed by the noob and gives rise to one of my complaints about Grails. For example, you may write a finder such as Book.findAllByAuthorLastNameAndPublicationDate(name, date). This is perfectly legitimate. When you try running your code with finder Book.findAllByAuthorLastNameAndPublicationDateAndBinding(name, date, binding), you'll find that it fails and will have a large stack trace on the console. You cannot have three conditions. This violates the principle that you should always write your code so that someone else has a clear mental model of what to expect. Unless you've read the one line in the Grails document that points this out or you've properly inferred from other writings, and it has stuck with you, you will run into this error. Perhaps this is a problem with the underlying Hibernate implementation. Either way, it is wrong. Never make people guess. I digress again. From here we are introduced to the use of criteria for more complex queries. This is barely touched upon, but we are promised that we will get a deeper introduction in a later chapter. Then come the concepts of filters. These are similar to filters in Java Servlets. They are quick and easy to implement. And, soon, we have our first filters written. Because the authentication is in place, we are not able to log into our application. There are no users! So, Jon takes us through adding users via our bootstrap class and we are introduced to the encryption function provided by the plug-in. This gives us the required background for encrypting the password when the user is created or updated. Jon did teach a trick here of which I was unaware. He updated the password field after calling hasErrors and save. This takes advantage of the Open Session in View pattern for hibernate. This means that changes to your object will not be persisted until all server-side operations have finished. Finally, we add some other features to our application: an improved permission denied page, a sign out link, and displaying the author of our messages. In the latter, we are introduced to services briefly and told we will learn more about services in an upcoming chapter. We are told that Grails supports the concept of a service layer, though little more. We are also required to relate messages to users. This was done simply, but Jon does not use belongsTo or hasMany properties to do so. We are also introduced to Hibernate's lazy loading feature, the n + 1 problem to which this gives rise, Hibernate fetch strategies, and using the eager strategy to resolve the n + 1 problem. One error was found in the code listings in the chapter on page 100. It is fairly minor. The author wrote Sha1Hash(user.password).toHex() and it should read Sha1Hash(userInstance.password).toHex(). I've submitted an error report to the publisher. Hopefully it will show up on the errata soon. Similarly, there was an instance where he used the word principle rather than principal on page 89 in the text that was not listed in the errata. I have not submitted this and likely will not. ![]()
Rate this article
Read more | 0 comments ![]()
Posted by Bill Turner
at 04:33 PM
![]() Link directly to this article.
![]() ![]() Tuesday, 7 July 2009
![]() Book - Grails 1.1 Web Application Development - Part 5
![]() Chapter 4 - Introduction To Groovy
Part 1 of this series can be seen here. Part 2 of this series can be seen here. Part 3 of this series can be seen here. Part 4 of this series can be seen here. Chapter 4 is the obligatory Groovy introduction. An in-depth introduction is not called for and has no place in an introductory Grails book. When it becomes necessary to have a deeper understanding, I recommend reading Groovy In Action by Koenig, et al, or Programming Groovy by Subramaniam. The chapter starts off with a brief introduction of Groovy and where it fits in the pantheon of languages. For those new to Grails, any fear of needing to learn a new language is quickly dispelled by showing how closely Groovy resembles java and how well it integrates with java. Of course, this only applies if you are currently a java programmer. Jon makes it clear that almost anything written in java can be run as Groovy, unfortunately, at no point does he tell us where this isn't the case. A simple pointer to the Differences from Java and to the Things you can do but better leave undone pages on the Groovy site would have been helpful. He covers all the basic features: everything an object, semicolons being optional, strings, GStrings, slashy strings, numbers, lists, maps and ranges. Truth and equality are likewise covered. Closures are explained. Closures are very important for the budding Groovy programmer. An understanding of closures is absolutely necessary for Grails development. Jon goes on to explain Plain Old Groovy Objects and how metaprogramming is used to add dynamic behavior, including how to use invokeMethod. This is a very interesting feature and goes to the heart of dynamic programming for those unfamiliar. While this knowledge is not critical to the Grails newbie, it is nice to know, and we are told that we will do more with it in a later chapter while developing a plug-in. Dynamic interception of calls is heavily used by Groovy Builders, which is the last section covered in the chapter. Armed with the knowledge in this chapter, we should be able to build a fairly sophisticated application. ![]()
Rate this article
Read more | 0 comments ![]()
Posted by Bill Turner
at 12:00 AM
![]() Link directly to this article.
![]() ![]() Thursday, 2 July 2009
![]() Book - Grails 1.1 Web Application Development - Part 4
![]() Chapter 3 - Posting Messages
Part 1 of this series can be seen here. Part 2 of this series can be seen here. Part 3 of this series can be seen here. The beginnings of the business goals of the project are implemented with this chapter. We create a new domain, Message, two views, one for adding messages, the other for viewing, along with corresponding controllers. Along the way, we learn about binding, validation and other user messages, the flash scope, redirection, the domain list method, several gsp (Groovy Server Pages) tags, layouts including the main.gsp and how SiteMesh renders layouts, and securing the site from XSS (cross site scripting) attacks. There were a few small mistatements or errors. First, when explaining how dateCreated and lastUpdated properties can be added to domains and will be updated for free, he states that they must have the corresponding constraints set to nullable:true. The corresponding example shows this, as well. Setting these properties to null is unnecessary. To be fair, this could've been true in an earlier release of Grails. The second issue is really minor. At one point Jon suggests you use the BootStrap.groovy to create some initial messages then says you can view the home page and see these messages. What he fails to mention is that the application needs to be restarted to pick up the changes to the BootStrap.groovy (unless that was just some strange issue on my side, but I think not). The final error was when HTML encoding was discussed. We are instructed to make the highlighted changes, though the code sample has no highlighting. I trust experienced developers can overcome this. In earlier chapters we were introduced to some command line arguments for creating domains and controllers. In this chapter, however, we are never introduced to generate-views. I thought this curious. Yes, generate-views would create several unneeded views, but I feel this being an introductory text, it would be better to demonstrate the command and direct the reader to delete the unnecessary views. The positive side of having the reader hand code the views is that it makes it far more obvious how various code fragments relate to the other parts of the application, as well as the introduced GSP tags. At the end of this chapter, the reader should now have an understanding of the basic building blocks of Grails. This chapter covered a lot of territory. Even so, it seemed simpler than the previous chapter, likely because domain development is so fundamental to most applications. Readers should have at this point a good idea of how rapid development can be with Grails. ![]()
Rate this article
Read more | 0 comments ![]()
Posted by Bill Turner
at 12:00 AM
![]() Link directly to this article.
![]() ![]() |
Latest Posts
19-Jun-2010
» Adding Feeds With Grails Plugins 26-Apr-2010 » April 2010 Groovy - Grails Job Market 13-Apr-2010 » GR8 in the US is Friday ![]() Archives
![]() Categories
![]() Bookmarks
![]() Authors
![]() Search
Syndicate This Site
|
|||||||||||||||||||||||||||||||||||||||||||||||||||