Evaluation Copy [Type the date]
GRAILS USING REST STUDENT LAB GUIDEBOOK
copyright@xcelframeworks
Evaluation Copy [Type the date]
TABLE OF CONTENTS Lab 1: Configuring & Installing Java & Grails……………...…3 Lab 2: Designing a Restful Webservice……………………….22 Lab 3: Creating Rest Service Using Grails……………………25 Lab 4: Working with Grails…………………………………………33 Lab 5: Adding Custom Controller……………………………….38 Lab 6: Enhancing Custom Marshaller…………………….......43 Lab 7: Working with Custom Renderer………………………50 Lab 8: Linking Resources……………………………………………54 Lab 9: Generating Rest Controller using Plugins………………………………………………………………………..58 Lab 10: Working with Custom Converters…………………..72 Lab 11: Rendering using GSP………………………………………81 Lab 12: Building Custom Plugins………………………………..92 Lab 13: Test Rest using Spock Framework……………….100 Lab 14: Securing Grails Apps using Spring………………..118
2
Evaluation Copy
Evaluation Copy [Type the date]
LAB 1: CONFIGURING AND INSTALLING JAVA & GRAILS
Step 1: Download and Install JAVA JDK
copyright@xcelframeworks
Evaluation Copy [Type the date]
Get the download link from java.com. Do not use the “Free JAVA Download” red button to download, as this download only acts as a plugin for your browser. At the bottom of the page click on the link “Developers”.
The Developers link will take you to the page from where you can download the JDK. Click on the highlighted link “JDK Downloads” as shown above.
4
Evaluation Copy
Evaluation Copy [Type the date]
From this page, you can choose to download JAVA Version 7 and ensure you download the latest update for the same version. Ensure you download the JDK as opposed to the JRE.
On the page that opens, you can choose to download the particular version for your platform. Verify the version of your platform before selecting to download (either 32 bit or 64 bit).
copyright@xcelframeworks
Evaluation Copy [Type the date]
After the download is done. Paste the JDK install file on your Desktop for easy access. Now double click on the install file to install JDK on your computer. Accept all the defaults and keep choosing “next” along the way as indicated on the images and let your JDK install. Step 2: Download and Install Grails:
To download Grails, go to: www.grails.org. On accessing the web page, you have to click on the “Download Grails” button, which will take you to the page as shown on the next image.
6
Evaluation Copy
Evaluation Copy [Type the date]
From this page, you have to click on the “Download Grails 2.4.2� button. This is the latest release of Grails.
copyright@xcelframeworks
Evaluation Copy [Type the date] There is no install file for Grails; all you have to do is unzip the files/libraries inside of the downloaded Grails zip file. Now you have to create a sub-directory under your C Drive titled “Grails” where you can put all your Grails libraries.
Open the Grails Zip file, drag the Grails libraries inside the zip file to the Grails sub-directory on your C Drive and let it uncompress. Once uncompressed you’ll find the Grails libraries under the Grails sub-directory on your C Drive. Step 3: Setting up Environment Variables. 8
Evaluation Copy
Evaluation Copy [Type the date]
To set up Environment Variable for JAVA and Grails, click on the “Start” menu, right click on the “Computer” and go to “Properties”. From Properties, go to “Advanced System Settings”. You’ll find the “Environment Variables” at the bottom as indicated on the image above.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Now let’s create a new Environment Variables for JAVA. Click “New” button under Environment Variables. Use JAVA_HOME (all characters are upper case) as the Variable Name.
For the Variable Value, you have to use the path to the directory where the JAVA libraries are installed. 1 0
Evaluation Copy
Evaluation Copy [Type the date]
Copy the path of the JAVA libraries directory and paste it on the Variable Value field. That completes creating an Environment Variable for JAVA.
Now let’s create an Environment Variable for Grails. We’ll follow the same procedure used for creating the JAVA Environment Variable. Select “New” button under the Environment Variables page. Use GRAILS_HOME (all characters are upper case) as the Value Name. copyright@xcelframeworks
Evaluation Copy [Type the date]
For the Variable Value, you have to use the path to the directory where the Grails libraries are stored.
Copy the path of the Grails libraries directory and paste it on the Variable Value field. 1 2
Evaluation Copy
Evaluation Copy [Type the date] That completes creating an Environment Variable for Grails.
Now we have to edit another variable which is the “Path”. The Path basically tells windows where to look for the executable files when you’re in the command line. Select the “Path” as listed above and click “Edit”.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Under “Variable Value” got to the very end and type “;%JAVA_HOME%\bin”. Then do the same for the Grails Variable, “;%GRAILS_HOME%\bon” as shown in the image below.
1 4
Evaluation Copy
Evaluation Copy [Type the date] Now the command line is all set up. Step 4: Testing Installation Configuration.
The first step is to open windows command line “cmd”. Test the Java version by entering “java –version”, this will bring up the Java version configured and installed.
copyright@xcelframeworks
Evaluation Copy [Type the date] Follow the same process for Grails. Enter “grails –version” to bring up the Grails version configured and installed.
Now create a test application to ensure the Grails installation is working correctly. Begin by entering “cd \grails”, then enter “grails create-app demo”. “Demo” here indicates the name of the test application.
1 6
Evaluation Copy
Evaluation Copy [Type the date]
After entering “grails create-app demo”, hit enter key. The test application “demo” will be created as shown above.
Now let’s run the test application, to do so, start by entering “cd demo” followed by “grails run-app”.
copyright@xcelframeworks
Evaluation Copy [Type the date]
The first time you run a Grails application, your windows firewall will prompt if you’d like to allow network access to Java. Here select “Allow Access”.
When the process is done it’ll show that the server is running and indicate a web address. 1 8
Evaluation Copy
Evaluation Copy [Type the date]
Now open a web browser, enter the web address as indicated. It’ll take you to the Grails Homepage, which means everything’s working correctly. Once Grails installation is done and tested next download GGTS from https://grails.org/products/ggts and follow the instructions to install. Its a eclipse based IDE. Install RestClient to be used in testing .Installation procedure is as follows: RESTClient can be downloaded from http://code.google.com/p/restclient/downloads/list. It is a single Jar file. To run it, you need to have Java 5 or above installed. After downloading, Windows users need to double-click to start the application. Non-Windows users, fire up your command prompt/shell, and issue: $ java -jar restclient-2.1-jar-with-dependencies.jar The UI Once it is started, you will see this UI:
copyright@xcelframeworks
Evaluation Copy [Type the date]
Installing curl on windows: There is an ordered series of steps to follow to install cURL on Windows. There are two libraries to install and they must be installed before cURL will work with SSL. Also, they must be installed in this order to work. Do not skip the step to install a recent certificate. 1. Install Visual C++ 2008 Redistributable Package. For 64-bit systems: Visual C++ 2008 Redistributables (x64) from http://www.microsoft.com/en-us/download/details.aspx?id=15336For 32-bit systems: Visual C++ 2008 Redistributables (x32) 2. Install Visual C++ 2010 Redistributable Package. For 64-bit systems: Visual C++ 2010 Redistributables (x64) from http://www.microsoft.com/en-us/download/details.aspx?id=14632For 32-bit systems: Visual C++ 2010 Redistributables (x32)
2 0
Evaluation Copy
Evaluation Copy [Type the date] 3. Install Win(32/64) OpenSSL v1.0.0k Light from http://www.shininglightpro.com/products/Win32OpenSSL.html.For 64bit systems: Win64 OpenSSL v1.0.0k LightFor 32-bit systems: Win32 OpenSSL v1.0.0k Light
4. In your browser, navigate to the cURL welcome page at http://curl.haxx.se and click Download
5. On the cURL Releases and Downloads page, click the link for the SSLenabled version for your computer's operating system, download the zip file, and install it in a new folder on your computer. The cURL website copyright@xcelframeworks
Evaluation Copy [Type the date] offers a wizard to find the appropriate version for your computer's operating system. For this tutorial, the 64-bit generic, SSL-enabled version for Windows is selected.
6. Install recent CA Certificates. Do not skip this step.Download cacert.pem, a recent copy of valid CERT files, from http://curl.haxx.se/docs/caextract.html. 7. Copy it to the same folder where you placed curl.exe and rename it curlca-bundle.crt
8. Invoke curl.exe from a command window (in Windows, click Start > Run and then enter "cmd" in the Run dialog box)
2 2
Evaluation Copy
Evaluation Copy [Type the date]
9. You can enter curl -- help to see a list of cURL commands.
copyright@xcelframeworks
Evaluation Copy [Type the date]
LAB 2: DESIGNING A RESTFUL WEBSERVICE
Activity 1: Applying RESTful Webservices Design Principle. Create a group of 3s and design a structure for Micro-blogging web service, which would be similar to Twitter. In this application users create accounts and then post entries. Try to identify and improve the services. The following are the steps to be used by the team to start the process.
Step 1: Requirement Gathering. Step 2: Resource Identification. Step 3: Resource Representation Definition. Step 4: URI Definition.
2 4
Evaluation Copy
Evaluation Copy [Type the date] The following are the output of the activity conducted by the team involved in the process. Step 1: Requirement Gathering. Provided below is the listing of the identified main business requirements: A web user creates an account with a username and a password. Registered users post blog entries to their accounts. A 160 characters limit on the messages must be set. Registered and Non-registered users view all blog entries. Registered and Non-registered user view user profiles. Registered users update their user profiles like password and others. Registered and Non-registered users search for terms in all their blog entries. Task: Perform a walk through to elaborate the use cases, identify and add a few more keeping in mind the basic objective of social networking sites. Participants Notes:
Step 2: Resource Identification: For the use case above, the team identified the following resources: 1. User. 2. List of users. 3. Message. 4. List of Messages. Identify if more resources are required for the business cases mentioned above. Participants Notes:
Step 3: Resource Representation. The team wants a well-designed service to support multiple resource representations. They want the following features regarding representation: 1. Format. 2. Link ability of representation.
copyright@xcelframeworks
Evaluation Copy [Type the date] For example, a list of users returns a structure of users with each element in the list with a direct URI to each element in the services (a link to user). Discuss the following representation forms? 1. Why XML? 2. Identify possible XML representations of each resource. Participant Notes Step 4: URI Definition. URI defines API, while designing the URI; the focus was on hierarchical, logical and best practices. Some of the identified URI are as follows. Evaluate the URIs and correct them if needed. 1. List of all users: http://localhost:8080/users 2. Representation of user with username: http://localhost:8080/users/username Identify and document other URIs to meet the use case requirements.
LAB 3: CREATING REST SERVICE USING GRAILS 2 6
Evaluation Copy
Evaluation Copy [Type the date]
There are various ways to implement REST, as there are lots of REST implementations around us. This Lab will show you how Grails compliments creation of REST API for web Applications. Step 1: Create a Grails Project as specified below.
Enter the name of Project as ProductManagement and visualize the directory structure created below.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Assume that this application provides the capability to “ABC Company” to create products and associate with the customer who bought those products. In this step we will be creating the Domain Classes and will set the relationship using GORM relationship clauses. We will consider bidirectional relation implementation. Step 2: Create a Customer Domain object (we can use script as well). We are using an IDE powered by plugins to create Domain Classes. In order to set relation we will be using “has many” and “belongs to” DSLs of GORM.
2 8
Evaluation Copy
Evaluation Copy [Type the date]
Step 3: Write the following domain class which is created using Customer name.
Step 4: Following the above step create Item Domain Class.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 5: Customize the url mapping of the Application. Since REST relies on the name of resources, it easily facilitates loose coupling. In order to specify Grails URL in Restful way, we will have to do it using UrlMappings class, present in conf folder of our application. Modify the default entry with the given entry to make the URL’s Restful with GET, PUT, POST and DELETE methods.
As of now we will use the default UrlMappings class entry without modifying. If the method is GET, it invokes show and the same applies for the other methods, which will invoke the corresponding action. Step 6:
3 0
Evaluation Copy
Evaluation Copy [Type the date] Prepare some records of Customer and Item in Bootstrap.groovy present in conf folder and add the following lines as specified below.
Step 7: Create Controllers using super class RestContoller. To do so, select controller, right click and select controller. The next step prompts you to select Domain Classes. Repeat the process for both the Domain Classes. Step 8: Modify the Controllers to extend RestControllers. The details of RestController are present in Lesson 3. Your Controllers must contain the following code after you update.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 9: We are almost done with creating our first basic Restful Service. Run the app using run as Grail-apps, as specified below.
3 2
Evaluation Copy
Evaluation Copy [Type the date]
Once you run-app, we will find that the project is rebuilt and internally the data from bootstrap.groovy is loaded in the database though the default one. It displays the following messages in the console ensuring that your web application with rest Service is ready to be used.
Using curl, we can test our rest service using the output as specified. Here we are using curl utility. To do this in the future labs, we will find a much more comprehensive way of testing the service. $ curl -X GET -H "Accept:application/json" http://localhost:8080/ProductManagement/customer $ curl -X GET -H "Accept:application/json" http://localhost:8080/ProductManagement/item If you don’t have the required utility installed, launch the browser and analyze the results as specified below. Output of: http://localhost:8080/ProductManagement/customer
Output of: http://localhost:8080/ProductManagement/item
copyright@xcelframeworks
Evaluation Copy [Type the date] When done, it will mean all your code is working fine. Though this is a simple Rest service it elaborates different segment that needs to be used to create and make the services available. We will improve this service further once we get to know more details of URI, Methods and Rendering Techniques.
LAB 4: WORKING WITH GRAILS 3 4
Evaluation Copy
Evaluation Copy [Type the date]
This lab illustrates working with various Grails components to build Rest based Web Service. We’re going to start off with the basic out-of-the-box functionality that Grails provides, explore the limitations and keep iterating towards our desired API. In the end we will have a complete Rest based service. Step 1: Creating Domain Objects: In the previous labs we tried creating domain object using GGTS. Follow the same steps to create following Domain Objects.
copyright@xcelframeworks
Evaluation Copy [Type the date]
In the Domain class shown above we have used @Resource annotation to keep the construction of web service simple and precise. Lets create a Product class as well (use the same steps as the ones in creating domain object).
In the Class Product shown above we have implemented relations to other Domain Objects where a product has many variations and the product belongs to manufacturers; this shows how we can specify relations among different domain objects. Now lets create the rest of the Domain Objects.
3 6
Evaluation Copy
Evaluation Copy [Type the date]
Now create the last dependent domain as specified below.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 2: Update BootStrap.groovy: Once the Domain Classes are ready we can edit our BootStrap.groovy to initialize the data to be used for testing. We need to populate the domain instances with some test data and it can be done using the statements below; specified in init method of BootStrap.groovy file.
Focus on manufacturers.each method, where we are populating the domain store with data. Step 3: Create Controller for managing phone as specified below: 3 8
Evaluation Copy
Evaluation Copy [Type the date]
Step 4: Update the urlmapping config as specified below:
Step 5: Run and test the Application using curl utility as specified below: curl -i -H "Accept: application/json" "localhost:8080/projectname/phones/2" Ensure you replace projectname with the name of your project. Step 5: Switch the content to XML as specified below: curl -i -H "Accept: application/xml" "localhost:8080/projectname /phones/1"
copyright@xcelframeworks
Evaluation Copy [Type the date]
LAB 5: ADDING CUSTOM CONTROLLERS
4 0
Evaluation Copy
Evaluation Copy [Type the date]
Adding Custom Marshallers: Lets write custom Marshaller and register it. This lab will help create custom Marshallers and write them up in resources.groovy. Analyze the output of the previous lab and we get following output for JSON and XML as specified below:
copyright@xcelframeworks
Evaluation Copy [Type the date]
To get a more descriptive output we will write our own custom Marshallers. Step 1: Write the following class that takes care of customizing the output. Create a class, which extends NamedMarshallerJson.
Step 2: Register it in resources.groovy as specified below: 4 2
Evaluation Copy
Evaluation Copy [Type the date]
Step 3: Analyze the output as specified below and run the application again to apply all the updates. curl -i -H "Accept: application/json" "localhost:8080/projectname/phones/2" And the output is specified as shown below:
copyright@xcelframeworks
Evaluation Copy [Type the date]
This shows you the descriptive output. Step 4: Build a similar XML Marshaller. Write the code as specified below:
4 4
Evaluation Copy
Evaluation Copy [Type the date]
Step 5: Test the output. (To be performed by the participants)
copyright@xcelframeworks
Evaluation Copy [Type the date]
LAB 6: ENHANCING THE CUSTOM MARSHALLER
4 6
Evaluation Copy
Evaluation Copy [Type the date]
This lab further improves the application from the previous. To support a compact and complete representation of our entities we can leverage Named Configurations for our object Marshallers. Unfortunately, the only mechanism that Grails has provided to do this is by making static method calls to the JSON and XML classes. Step 1: Create a NamedMarshaller as specified below:
Step 2: Create NamedJsonMarshaller and Named XMLMarshaller extending NamedMarshaller as specified below:
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 3: Refactor the previous Marshaller as specified below:
4 8
Evaluation Copy
Evaluation Copy [Type the date]
Step 4: Write a compact version of JSON as specified below:
copyright@xcelframeworks
Evaluation Copy [Type the date] Step 5: Map our configuration name. In our case it can be compact or complete by configuring marshaller beans in resources.groovy as specified below:
Step 6: Add a Grails service that implements ContextAware to make managing new Marshallers easy as specified below:
Step 7: Update Bootstrap.groovy. We just need to inject this service and call our initialize method as specified below: 5 Evaluation Copy 0
Evaluation Copy [Type the date]
Step 8: Implement our controller for our Phone resource as specified below:
Step 9: Update the urlMapping in UrlMappings.groovy as specified below:
Step 10: Test the application after running it. (You’ll need to rebuild if errors persists). curl -i -H "Accept: application/json" \ "localhost:8080/projectname/phones/2?detail=complete"
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 11: Test the output.
Step 12: Test the output for compact using following curl: curl -i -H "Accept: application/json" \ "localhost:8080/projectname/phones/2?detail=compact" And the output would be:
5 2
Evaluation Copy
Evaluation Copy [Type the date]
copyright@xcelframeworks
Evaluation Copy [Type the date]
LAB 7: WORKING WITH CUSTOM RENDERER
This lab helps us create Custom Renderers that lets us customize the structure of our responses and handle our requirements including related resources and Metadata. We’ll use this renderer anytime we want to render a single Phone resource. Our general approach will be to use a default detail level of ‘compact’ in our renderer, then handle the situations where we want to use a ‘complete’ detail level in our controller logic by default. Step 1: Create a Basic renderer as specified below:
Step 2: 5 4
Evaluation Copy
Evaluation Copy [Type the date] In resources.groovy, we’ll map the renderer for Phone class as specified below:
Step 3: Then finally, in the Phone Controller class we’ll slightly modify the logic as specified below:
The important thing to notice in our controller is that we’re now able to pass any arbitrary arguments from our controller along to our renderer. This is the fundamental mechanism that will allow us to build our desired API. Step 4: We need to add a Collection renderer as specified below:
Step 5: Map the Collection renderer in resources.groovy as specified below:
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 6: Modify our controller for our index method as shown below:
Step 7: Add the following Meta map parameter to our render argument within our Controller.
Step 8: In our response, we want this to render within our main JSON response object with a name of “meta” containing key value pairs of our metadata. In this case, we’d expect the result to look something similar to the one show below:
Step 9: 5 6
Evaluation Copy
Evaluation Copy [Type the date] Place the following request with our current renderer: curl -i -H "Accept: application/json" \ "localhost:8080/projectname/phones" It will produce only an array of our marshalled phone JSON as specified below:
LAB 8: LINKING RESOURCES (Displaying links related to specific resources)
copyright@xcelframeworks
Evaluation Copy [Type the date]
This lab elaborates the usage of linking. For example, in our existing case, in any time we render a Phone object we may want to include links to the phone’s manufacturer, or to customer reviews for the phone, or to the images of the phone. This might look something as shown below:
To get the above output we have to do the following modifications to our existing application.
5 8
Evaluation Copy
Evaluation Copy [Type the date] We can add the linking directly to our Marshaller. With some minor adjustments we can add link generation support and directly add links to our marshalled JSON. To do this, we need to ensure that the closure that returns the marshalled JSON has access to a Grails link generator. You can accomplish this in different ways, but the one I chose are described in details below: Step 1: Add a LinkGenerator argument to closures that will include links. For instance, we can modify the closure in PhoneMarshallerJson as follows:
Step 2: Now this closure is a bit different from the others already present in namedMarshaller, it needs to argument instead of just the object to be marshalled. To handle this, we’ll leverage Groovy’s ability to curry closures. In our base marshaller class, we’ll use a linkGenerator as an argument anytime our closure allows more than a single parameter. Add the following in your NamedMarshaller:
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 3: Rebuild the project and run it. Use the following curl statement to see the output.
curl i H "Accept: application/json"\ "localhost:8080/projectname/phones/2? detail=complete"
6 0
Evaluation Copy
Evaluation Copy [Type the date]
copyright@xcelframeworks
Evaluation Copy [Type the date]
LAB 9: GENERATING REST CONTROLLER USING PLUGINS
Step 1: Create a Domain Class called Project in a new project named lab5 and generate the controller, which internally uses a scaffolding plugin. Before generating let’s verify the plugin is configured.
All plugins are configured in BuildConfig.groovy. In Grails 2.4.2 scaffolding is already configured. Step 2: Create the Domain class as specified below: 6 2
Evaluation Copy
Evaluation Copy [Type the date]
Step 3: Create Controller for Customer Domain Class:
While generating, it selects the Domain class for which you want to create controller. You will find an empty Controller as specified below:
We are going to add functionality to this Controller to build a Restful Application. Step 4: Provide some records in Bootstrap.Groovy as specified below to facilitate initial data loading: copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 5: Edit UrlMappings.groovy file. Let’s decide the functionality that we expect for our current controller to support and specify appropriate URI in URLMappings.grrovy file. In the Mapping file shown below, we mapped/customer to a corresponding controller (we still have to work on the Controller, coming next), and the actions are mapped such that the GET requests go to the list action of the controller and POST is forwarded to the save action. For a different URL pattern/customer/$id we have also provided mappings for its supported HTTP methods: GET, PUT and DELETE. Ensure you edit your UrlMappings.groovy present in the conf folder of your Grails Application.
6 4
Evaluation Copy
Evaluation Copy [Type the date]
Groovy/Grails does it’s magic by mapping the controllers with the uri in a request context. Step 6: Add list method to controller. It’s simple and you need to define an action closure in CustomerController.Open CustomController, and add the following entry to it.
This defines an action for list uri (see UrlMappings.groovy) file. Step 7: Let’s build and run the project to test how this single action is implemented. Step 8: Test the method. We will be using RestClient instead of curl (you can use curl as well) to get you familiarized with the Restclient tool as well. (If it’s not installed, install it as specified in the Installation guide). Launch the tool by running it. You will find a window being launched as specified below.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Let’s test the first url and see the output. Enter url in the url segment and press execute as shown below. 6 6
Evaluation Copy
Evaluation Copy [Type the date]
Analyze the output shown below:
Once you see the status as 200 OK, look at the body for the content as specified below:
copyright@xcelframeworks
Evaluation Copy [Type the date]
You may not get the output the way its shown in the screen above, you need to indent it using indent context menu as specified below:
Step 9: 6 8
Evaluation Copy
Evaluation Copy [Type the date] Now lets quickly write the rest of the methods in the CustomerController to implement create, update, delete and yes action to get us the record on the basis of ID. Step 9.1: Implementing Create. Add the following code in your Controller. This method reads your request body and extracts content as xml. Observe the code, we are creating instance reading attribute from incoming request which is xml and finally we are saving it by making call to the domain objects save method (don’t worry you need not write as its already implicitly generated). If your applied validation domain fails there is a method to report it.
Step 9.2: Implement Delete method. This method deletes record from the mapped Database. Let’s look at the implementation specified below:
copyright@xcelframeworks
Evaluation Copy [Type the date]
Observe the domain objects method call and the status code. Step 9.3: After implementing delete and create, we need to provide a closure for the update as well. The code is specified below. Update your controller with this code.
Step 9.4: The final step is to add our show action that displays the specific record, depending on the URI specified. Observe the code shown below:
7 0
Evaluation Copy
Evaluation Copy [Type the date]
Now that all of our code is specified, it’s time to build and test the applications functionality. We would be using RestClient, though you can use curl as specified in previous lab. Test for Create: Launch RestClient and select POST method. Enter details of the data that you want to add. In the code it’s specified that we need xml, which will be added to the database.
Next Click on the body and enter the xml data as specified below.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Ensure you select string body and text/plain:charset=UTF-8 as specified above, and click on execute. Observe the response section with the 201-response code, which specifies the record created as specified below.
Verify that the record is inserted by executing list. To do that, you have to select Get as method and execute in rest client. Verify that it displays the record you added recently.
7 2
Evaluation Copy
Evaluation Copy [Type the date]
Test For Delete: To delete we will again follow the steps with the difference that we need to pass the ID of the record we want to delete as part of our URI. Once it is deleted, check the response code.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Once we have selected it click on execute to see the output displayed in the response section as shown below.
7 4
Evaluation Copy
Evaluation Copy [Type the date]
Test for Update: Select the record you want to change; in this case we are changing firstName of the customer as displayed below:
copyright@xcelframeworks
Evaluation Copy [Type the date] Click on execute and check the response code as specified below:
This Lab Exercise ends with the Tests being successful.
7 6
Evaluation Copy
Evaluation Copy [Type the date]
LAB 10: WORKING WITH CUSTOM CONVERTERS
Step 1: Create a Grails Project named Lab 8 and create a City domain class. Enter the following code in the domain class.
copyright@xcelframeworks
Evaluation Copy [Type the date]
In this class new elements are introduced like @ToString with includeNames, includeFields and excludes properties . We add @EqualsAnd HasCode annotation to ensure that they are generated as a part of the bytecode. Also note the constraints added in constraint section. Step 2: Populate the DB with some test data as specified below in BootStrap.groovy file:
Step 3: Create and run the Restful Controller.
7 8
Evaluation Copy
Evaluation Copy [Type the date]
Once it’s created, test your application using RestClient.
Step 4: Now change the header as specified below in the RestClient, test it again to get xml data. This illustrates how RestController provides automatic marshaling and conversion capability.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 5: Providing an alternate URI to REST service: Provide an alternate URI by entering the url specified below in the urlMappings.groovy file.
Step 6: Test the new URI and see the output 8 0
Evaluation Copy
Evaluation Copy [Type the date]
Up till now, we have seen the basic automated approach of controlling the Marshaling. Step 7: Controlling the content rendering by using includes and excludes in resources.groovy, under springs/resources folder.
If you’re confused as to how you are supposed to name the beans, rest assure, this is totally up to you and their names are not important. Grails will scan the application context for all available beans. So just make sure the name is somehow meaningful. Step 8: Test the following by using RestClient again and compare the output you found, dateCreated, excluded from the output. copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 9: Add the XMLCollectionRenderer and JSONCollectionRenderer to apply on the list to exclude class and dateCreated as specified below in urlMappings.groovy.
8 2
Evaluation Copy
Evaluation Copy [Type the date]
Step 10: Test the output using Test client as specified below:
Step 11: Create a Custom Marshaller. To do this, create a Groovy class in src/groovy with the following code. We will register the Marshaller by using JSON.registerObjectMarshaller.
Step 12: copyright@xcelframeworks
Evaluation Copy [Type the date] Register the Custom Marshaller as spring bean. Comment on the other lines that are already added to this file in the previous steps and add the line to register as shown below:
Step 13: We also need to register the spring beans in Bootstrap.grrovy to ensure loading as specified below. Don’t forget to import the package of spring, which contains WebApplicationContextUtils package import org.springframework.web.context.support.WebApplicationContextUtils, and ensure it’s added in Bootstrap.groovy file.
8 4
Evaluation Copy
Evaluation Copy [Type the date]
Step 14: Test the service by using RestClient as specified below:
copyright@xcelframeworks
Evaluation Copy [Type the date]
LAB 11: RENDERING USING GSP
8 6
Evaluation Copy
Evaluation Copy [Type the date]
Step 1: Create a Grail application “Lab 9� with the objective of understanding GSP with a domain class to create and maintain a Blog Entry. The content of the class is specified below:
Step 2: Create the controller and use static scaffold to generate views for the Entry class as specified below. We will be customizing the view as per our need at a later stage.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 3: Let’s run the application and test the different views generated with the controllers, which are implicitly generated with all the actions. Navigate through each page and see the objective of them all. The index page is displayed below, now write the URL in the browser as specified below. Ensure that your controller is part of the controller List as well.
Step 4: Click on the controller of the Page for Entry with various features as shown below: 8 Evaluation Copy 8
Evaluation Copy [Type the date]
As of now, there are no records added so the list displays blank. Observe the logo and other themes, which we will customize further. Step 5: Click on New Entry to add some entry records using the form as displayed below. After entering the details we get the following page (ensure you click on create after entering details).
This form contains all the basic functionalities that you would like on your Resource. Add a few more to get more records by following the previous steps. Step 6: Click on the List to see all the records as displayed below.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 7: Click on Grails and observe the URL and the output displayed below.
Step 8: Generate views for your Domain class to get the gsp and it’s content, this way you can customize it as per our need.
Specify the domain class as Entry to generate the page. Once it’s done, you will find certain gsp resources added to the directory structure as specified below.
9 0
Evaluation Copy
Evaluation Copy [Type the date]
Step 9: Run the App again and review the output. Spend some time to navigate and ensure all the tasks are getting completed successfully. Step 10: Changing the logo and other display elements including css.gsp is a templatebased markup. We have the main.gsp, which contains the template that is to be shared across the application. Let’s change some entries in this, we are changing the logo and editing the following section as specified below.
copyright@xcelframeworks
Evaluation Copy [Type the date] Step 11: Rerun the application and observe the content will change on all the pages. A sample index is specified below.
Step 12: Creating Taglib in gsp is simple. If you have experienced the complexity of creating Taglib in Java you will appreciate it. Create a Taglib using the following steps.
9 2
Evaluation Copy
Evaluation Copy [Type the date]
Step 13: After entering the name as footer, click finish and you will see various classes created as displayed below.
Step 14: Enter the following code in FooterTagLib.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Thatâ&#x20AC;&#x2122;s all it takes to create a new <g:thisYear /> tag.out. It is the output stream, and you are sending the current year to it. The format() method on Date is identical to the one found in java.text.Simple DateFormat. Groovy metaprograms this new method onto java.util.Date as a convenience, much like GORM metaprograms list(), save(), and delete() methods onto your domain classes. Step 15: Edit main.jsp and add the following code as specified below.
Step 16: Run the program and test the output of the pages, you will find the content added as specified below. 9 4
Evaluation Copy
Evaluation Copy [Type the date]
Step 17: We have done some modifications but till now we have not got proper hold of contents for manipulating it. Letâ&#x20AC;&#x2122;s work on customizing the template, using the following steps. Generate template by using install template Grails command.
Step 18: Click on the Grails command and use install-templates command from the following list as specified below. Place the cursor in text filed and press CTRL+SPACEBAR.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 19: See the message in the console prompt as specified below.
Step 20: This command generates the following directory structure.
9 6
Evaluation Copy
Evaluation Copy [Type the date]
Step 21: We will get detailed content as listed below:
Step 22: Open the files in the scaffolding folder and modify some properties to observe the output. Spend some 10-15 minutes to see the structure. The detailed GSP is out of scope of this course. The objective of this lab was to ensure that you understand the rendering made possible using GSP.
copyright@xcelframeworks
Evaluation Copy [Type the date]
LAB 12: BUILDING CUSTOM PLUGINS
Step 1: Create a Grails plugin project and name it as directed in the dialog below. 9 8
Evaluation Copy
Evaluation Copy [Type the date]
We do not name the project with a lab number because we cannot specify numbers in plugin projects.
Step 2: Observe the directory structure of this project and the plugin descriptor file where we have to specify the details of the plugin that we are planning to create.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 3: Analysis of the plugin descriptor file: Open the file and look at some of the entries, a small snapshot is provided below.
1 0 0
Evaluation Copy
Evaluation Copy [Type the date]
This file contains the metadata for your plug-in, the version number, the version of Grails your plug-in depends on, any other plug-ins that your plug-in depends on, and so forth. If you want to make this a public plug-in that other developers can download from the Plugins portal, you should fill in the author details and give it a compelling description. The file's contents are read and automatically displayed on the Grails website every time you check your plug-in into the public Subversion repository. Step 4: Create a SmallUrl Class as specified below.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 5: Write the following code in the class created above.
1 0 2
Evaluation Copy
Evaluation Copy [Type the date]
Step 6: Create an IsGd class; the Is.Gd (pronounced â&#x20AC;&#x153;is goodâ&#x20AC;?) service boasts a shorter domain name and shorter encoded URLs than TinyUrl.com. Visit http://is.gd to experiment with the web interface.
Step 7: Create a Service as specified below.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 8: Write the service class as specified below.
Note that the isgd() method logs any attempt to shorten an invalid URL. All Grails artifacts are injected with a log object at run time.
1 0 4
Evaluation Copy
Evaluation Copy [Type the date] You can call methods on the log object that correspond to the desired log level: debug, info, error, and so on. Step 9: Package and deploy the plug-in as follow, use Grail command as specified below.
Step 10: Packaging the plugin project.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Click on run. Step 11: Once created you will find the distributable plugin as specified below in the directory.
1 0 6
Evaluation Copy
Evaluation Copy [Type the date]
You can create any element of Grails to be part of the plugins as specified. If you want to distribute the plugin to every one, you need to publish it. If ShortenUrl were a public plug-in, you could type Grails release-plugin to push your changes to the Grails Plugins portal. Anyone could then type Grails install-plugin shortenurl to integrate it with his or her project. But you can also install private plug-ins locally just as easily: all you need to do is supply the full path to the ZIP file on your local file system.
LAB 13: TESTING REST USING SPOCK FRAMEWORK
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 1: Letâ&#x20AC;&#x2122;s create a Grails Project with a certain Domain classes and controller to write the test cases using Spock Framework. Create it using GGTS command. Step 2: Configure the required plugins for Spock Framework as specified below:
1 0 8
Evaluation Copy
Evaluation Copy [Type the date]
Step 3: Also ensure the following entries are in the BootStrap.groovy
Step 4: Create the following domain objects as specified below.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 5: 1 Evaluation Copy 1 0
Evaluation Copy [Type the date] Create the following Controllers. Generate Controller for the Author using Generate Controller, it will generate the complete code.
Step 6: Create a Controller, BookController, as specified below.
copyright@xcelframeworks
Evaluation Copy [Type the date] Step 7: Write the service as follows using create-service, and rovie the following code in the service class.
Write the following Test Code in the generated Test Class, under the Unit Test. (AuthorSpec) package com.webage import grails.test.mixin.TestFor import spock.lang.Specification import com.webage.Author /** * See the API for {@link grails.test.mixin.domain.DomainClassUnitTestMixin} for usage instructions */ @TestFor(Author) class AuthorSpec extends Specification { def "find author by firstname and lastname"() { setup: mockDomain(Author) when: new Author(firstname: firstname, lastname: lastname).save() then: Author.findByFirstnameAndLastname(firstname, lastname) != null where: firstname = "John" lastname = "Doe" } def "firstname constraints"() { setup: 1 1 2
Evaluation Copy
Evaluation Copy [Type the date] mockForConstraintsTests(Author) when: def author = new Author(lastname: "Doe") //Assignment of possible NULL values must be done via property assignment because assignment via map and constructor now leads to NULL if String is "" //See http://grails.org/doc/latest/ref/Constraints/nullable.html for more details author.firstname = firstname author.validate() then: author.hasErrors() == !valid where: firstname | valid "123456789012345678901" | false //Firstname must not have more than 20 characters "12345678901234567890" | true "" | false //Firstname must not be blank } def "lastname constraints"() { setup: mockForConstraintsTests(Author) when: def author = new Author(firstname: "John") //Assignment of possible NULL values must be done via property assignment because assignment via map and constructor now leads to NULL if String is "" //See http://grails.org/doc/latest/ref/Constraints/nullable.html for more details author.lastname = lastname author.validate() then: author.hasErrors() == !valid where: lastname | valid "123456789012345678901" | false "12345678901234567890" | true "" | false
copyright@xcelframeworks
Evaluation Copy [Type the date] Step 8: Write the following Test for AuthorController. (AuthorController Spec) package com.webage import grails.test.mixin.Mock import grails.test.mixin.TestFor import spock.lang.Specification /** * See the API for {@link grails.test.mixin.web.ControllerUnitTestMixin} for usage instructions */ @TestFor(AuthorController) @Mock([Author]) class AuthorControllerSpec extends Specification { def 'index action: 1 author'() { setup: authorInstance.save() expect: controller.index() == [authorInstanceList: [authorInstance], authorInstanceTotal: 1] where: authorInstance = new Author(firstname: "John", lastname: "Doe") } def 'index action: 2 authors and max = 1'() { setup: fistAuthorInstance.save() secondAuthorInstance.save() controller.params.max = 1 expect: controller.index() == [authorInstanceList: [fistAuthorInstance], authorInstanceTotal: 2] where: fistAuthorInstance = new Author(firstname: "John1", lastname: "Doe1") secondAuthorInstance = new Author(firstname: "John2", lastname: "Doe2") } def "create action"() { 1 Evaluation Copy 1 4
Evaluation Copy [Type the date]
setup: controller.params.firstname = firstname controller.params.lastname = lastname when: def model = controller.create() then: model.authorInstance != null model.authorInstance.firstname == firstname model.authorInstance.lastname == lastname where: firstname = "John" lastname = "Doe" } def 'save action: valid author'() { setup: controller.params.firstname = "John" controller.params.lastname = "Doe" when: request.method = 'POST' controller.save() then: response.redirectUrl != null response.redirectUrl.endsWith "show/1" controller.flash.message != null } def 'save action: invalid author'() { setup: controller.params.firstname = firstname controller.params.lastname = lastname when: request.method = 'POST' controller.save() then: view != null view.endsWith "create" model.authorInstance.firstname == firstname model.authorInstance.lastname == null
copyright@xcelframeworks
Evaluation Copy [Type the date]
where: firstname = "John" lastname = "" } def 'show action: existing author'() { setup: authorInstance.save() controller.params.id = authorInstance.id expect: controller.show() == [authorInstance: authorInstance] where: authorInstance = new Author(firstname: "John", lastname: "Doe") } def 'show action: not existing author'() { setup: controller.params.id = 1L when: controller.show() then: response.redirectUrl != null response.redirectUrl.endsWith"list" controller.flash.message != null } def 'edit action: existing author'() { setup: authorInstance.save() controller.params.id = authorInstance.id expect: controller.edit() == [authorInstance: authorInstance] where: authorInstance = new Author(firstname: "John", lastname: "Doe") } 1 1 6
Evaluation Copy
Evaluation Copy [Type the date] def 'edit action: not existing author'() { setup: controller.params.id = 1L when: controller.edit() then: response.redirectUrl != null response.redirectUrl.endsWith "list" controller.flash.message != null } def 'update action: valid author'() { setup: authorInstance.save() controller.params.firstname = "John changed" controller.params.lastname = "Doe changed" controller.params.version = authorInstance.version controller.params.id = authorInstance.id when: request.method = 'POST' controller.update() then: response.redirectUrl != null response.redirectUrl.endsWith "show/1" controller.flash.message != null where: authorInstance = new Author(firstname: "John", lastname: "Doe", version: 1) } /** * Testing optimistic locking currently not possible due to this bug: http://jira.grails.org/browse/GRAILS-9862 def 'update action: optimistic locking'() { setup: authorInstance = authorInstance.save() assert authorInstance.id when: controller.params.firstname = "John changed" controller.params.lastname = "Doe changed"
copyright@xcelframeworks
Evaluation Copy [Type the date] //Decrease version of edited object to enforce optimistic locking validation controller.params.version = authorInstance.version -1 controller.params.id = authorInstance.id controller.update() then: view == "edit" model.authorInstance == authorInstance model.authorInstance.hasErrors() where: authorInstance = new Author(firstname: "John", lastname: "Doe") } **/ } Step 9: Write the Test Case for the Book Domain Class as specified below, named BookSpec. package com.webage import grails.test.mixin.TestFor import spock.lang.Specification import com.webage.Book import com.webage.Author /** * See the API for {@link grails.test.mixin.domain.DomainClassUnitTestMixin} for usage instructions */ @TestFor(Book) class BookSpec extends Specification { def "find book by title"() { setup: mockDomain(Book) mockDomain(Author) when: new Book(title: title,author:new Author(firstname:"John",lastname:"Doe").save()).save() then: Book.findByTitle(title) != null where: title = "Nice book" } def "title not longer than 20 characters"() { 1 Evaluation Copy 1 8
Evaluation Copy [Type the date] setup: mockForConstraintsTests(Book) mockDomain(Author) when: def book =new Book(title:title, author:new Author(firstname:"John",lastname:"Doe").save()) book.validate() then: book.errors.hasFieldErrors("title") where: title="123456789012345678901" } def "title not blank"() { setup: mockForConstraintsTests(Book) mockDomain(Author) when: def book =new Book(title:title, author:new Author(firstname:"John",lastname:"Doe").save()) book.validate() then: book.errors.hasFieldErrors("title") where: title="" } def "author not blank"() { setup: mockForConstraintsTests(Book) mockDomain(Author) when: def book =new Book(title:"nice title", author:null) book.validate() then: book.errors.hasFieldErrors("author") }
copyright@xcelframeworks
Evaluation Copy [Type the date] } Step 10: Write a Test for Gutten. package com.webage import grails.test.mixin.Mock import grails.test.mixin.TestFor import spock.lang.Specification import com.webage.Book import com.webage.Author /** * See the API for {@link grails.test.mixin.services.ServiceUnitTestMixin} for usage instructions */ @TestFor(GuttenbergService) @Mock([Author,Book]) class GuttenbergServiceSpec extends Specification { def "when creating thesis a new book is created"() { when: authorInstance.save() service.createThesis(authorInstance.id) then: Book.count() == 1 where: authorInstance = new Author(firstname: "John", lastname: "Doe") } def "when creating thesis author is assigned to thesis"() { //3. Call the method to test when: authorInstance.save() def thesis = service.createThesis(authorInstance.id) then: //4. Make asserts on the result thesis != null thesis.author.id == authorInstance.id //1. Create a dummy author instance used for the test. This instance has NO id yet 1 Evaluation Copy 2 0
Evaluation Copy [Type the date] where: authorInstance = new Author(firstname: "John", lastname: "Doe") } def "when creating guttenberg thesis title is set"() { when: authorInstance.save() def thesis = service.createThesis(authorInstance.id) then: thesis != null thesis.title == "My copied thesis" where: authorInstance = new Author(firstname: "John", lastname: "Doe") } } Step 11: Provide some data in Bootstrap.groovy as follows: import com.webage.Author import com.webage.Book class BootStrap { def init = { servletContext -> Author glenSmith = new Author(firstname:"Glen",lastname:"Smith").save(failOnError:true) Book grailsInAction = new Book(title:"Grails in Action",author:glenSmith).save(failOnError:true) Author robertMartin = new Author(firstname:"Robert",lastname:"Martin").save(failOnError:true) Book cleanCode = new Book(title:"Clean Code",author:robertMartin).save(failOnError:true) Author joshuaBloch = new Author(firstname:"Joshua",lastname:"Bloch").save(failOnError:true) Book effectiveJava = new Book(title:"Effective Java",author:joshuaBloch).save(failOnError:true)
copyright@xcelframeworks
Evaluation Copy [Type the date] } def destroy = {
}
} Step 12: Run the Application using run test-app, using the following GGTS command.
Step 13: Once it starts, it will download the plugins and run the test giving you the following output:
1 2 2
Evaluation Copy
Evaluation Copy [Type the date]
Step 14: Go to JUnit option and observe the output in JUnit runner.
Step 15: Observe the files generated in the directory structure:
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 16: Locate the file, index.html, and open it in a browser:
1 2 4
Evaluation Copy
Evaluation Copy [Type the date]
Step 17: Once you launch it in the browser, you will find that the index takes some time in visualizing the report.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 18: Click on Author spec and observe the result (do it for all the links).
1 2 6
Evaluation Copy
Evaluation Copy [Type the date]
LAB 14: SECURING GRAILS APPS USING SPRING
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 1: Create a Grails Project â&#x20AC;&#x153;lab12â&#x20AC;? and add Spring Security to it by editing BuildConfig.groovy. Add the following repository to the repository section.
Step 2: Edit BuildConfig.groovy and add the following plugins in the plugin section as specified below.
Step 3: Execute the following command to generate the security artifacts using following steps. a) Use the following steps to add the added plugins.
1 2 8
Evaluation Copy
Evaluation Copy [Type the date]
b) Refresh dependencies as specified below. Once the plugins are installed you will see the following messages in the command console.
c) Install the plugin using s2-quickstart com.testapp User Role Grails Command. We can use the following to do that.
copyright@xcelframeworks
Evaluation Copy [Type the date]
d) Specify the command in the prompt and execute the command.
1 3 0
Evaluation Copy
Evaluation Copy [Type the date]
Click on run and you will find the command execution starts to create the required artifacts to be used in implementing security.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 4: Open and verify config.groovy..
Step 5: Add content to BootStrap.groovy for some records since this plugin does not provide support to CRUID operation. Enter the code in BootStrap.groovy as given below.
1 3 2
Evaluation Copy
Evaluation Copy [Type the date]
Step 6: Create a Controller as specified below. Leave the default entry in the Controller as specified below.
Step 7: Generate Controllers and Views for user and role classes as specified below. Repeat this step for user and role.
copyright@xcelframeworks
Evaluation Copy [Type the date]
Step 8: Once the Controllers and Views are generated, run the application. Step 9: Edit the SecureController and see the output as specified below.
1 3 4
Evaluation Copy
Evaluation Copy [Type the date]
Step 10: Test the application for security test. If it is not successful, check your plug-ins and redo the task, deleting the project and recreating it carefully.
copyright@xcelframeworks