Showing posts with label Grails. Show all posts
Showing posts with label Grails. Show all posts

Saturday, July 20, 2013

Domeo, Annotation Framework, Catch Annotation Hub and Grails Plugins architecture

I found organizing big projects in components always a reassuring idea.
Component Oriented Programming? I let you decide if that is what I mean. I’ve read several discussion on the topic Component Oriented Programming vs. Object Oriented Programming and I am personally one of those who believes the two strategies are complementary and not in competition. As I am not interested in debating the theoretical differences, I would stick to what I normally do and not what I think.
That is one of the reasons I’ve always liked - and I still like - OSGi and that is also one of the reasons I’ve been always attracted by the Grails Plugins architecture.
The components oriented approach did not always pay off. Occasionally I just gave up when I found myself fighting with the technology of the moment, which was getting a little on the way. I am sure most of my problems were related to my limited knowledge of that particular technology... still, deadlines are deadlines and I needed to get things done.
I am certainly not the first nor the last developer celebrating the Grails Plugin Oriented Architecture. Here is a blog post that shows how a domain class defined in a plugin can be reused by other components of the architecture.

However, I have been thinking about the OSGi-based Eclipse architecture for a long time and I even tried to develop a lighter Java framework for developing applications along the same lines. Naturally, since I've been using Grails, I’ve been thinking on how to reproduce the same behavior in web applications by using Grails plugins. Basically I am talking about conveniently leveraging plugins to benefit from all the perks of the Grails platform: domain classes, services, controllers and views. I will defer to future posts some of the technical details. Meanwhile I wish to provide a little context.

I am thinking of leveraging the plugin architecture for a project called CATCH that I’ve been working on for a tiny grant awarded by Harvard Library Labs. As the Domeo Annotation Tool already provided some of the features I need for CATCH I've decided to refactor and spin off some of its components. I've  created a new GitHub project called Annotation Framework which will collect all the new improved modules that will be later used by both Domeo and CATCH


CATCH Annotation Hub

The goal of CATCH is to provide a hub for collecting/searching and sharing annotation produced by several clients. These includes the Domeo annotation client, HighBrow - an annotation client developed at Harvard by Reinhard Engels - and annotator.js an open-source JavaScript library and tool - developed by Nick Stenning  - that can be added to any webpage to make it annotatable.

Both CATCH and the older sister project Domeo are meant to be installed in several instances that should be able to communicate with each other in a federated architecture. You can think this as a series of Annotation Framework Nodes that are distributed and connected so that when a user performs a search on one of the nodes, it can also find results that have been created and stored in other authorized/linked nodes. All with access control...


Wednesday, May 09, 2012

Running GWT 2.4.0 with STS 2.9.1 and Grails 2.0.3

Alright, if you followed all the steps of the previous post, you should be able to see the results of the GWT code execution at the address:
http://localhost:8080/{projectname}/hello.gsp 
As you might have noticed, I previously asked the plugin to compile the GWT code (compile-gwt-modules). That operation takes some seconds as the entire artifact is recompiled (when the application will grow, the compilation can last minutes).  Luckily there is an alternative, the hosted mode. When an application is running in hosted mode, the Java Virtual Machine (JVM) is actually executing the application code as compiled Java bytecode, using GWT plumbing to automate an embedded browser window. This means (1) we don't need to recompile the code as STS is producing the Java bytecode for us incrementally (2) the debugging facilities of your IDE are available to debug both your client-side GWT code and any server-side Java code as well.

First we start the grails application (run-app), second, in the command prompt we type:
run-gwt-client
This last command starts the hosted mode and you should see appearing a window like the one depicted in figure 1. 

Figure 1: hosted mode window.

Now we can 'copy to clipboard' and open that link in a web browser:
http://localhost:8080/GwtTest/hello.gsp?gwt.codesvr=127.0.0.1:9997
The page should appear in the window and the alert 'hello' should display. Now you can verify the usefulness of the hosted mode by updating the alert - in the class HelloApp.java from 'hello' to 'hello me' - and reloading the page. The alert will display the new string without you having to trigger the GWT code compilation manually. And this will result in a huge save of time. (Read more)

Note. Remember that the manual compilation is still necessary prior to deployment as the deployed version of the page will run the compiled JavaScript.


Friday, May 04, 2012

Setting up STS 2.9.1, Grails 2.0.3 and GWT 2.4.0

If you need to integrate Grails and Google Web Toolkit (GWT) here is a list of tips. If you are interested in Grails you might want to consider the SpringSource Tool Suite or briefly STS. I usually install the STS package in a directory which name includes the version of the STS software to make sure multiple versions of the tool can beautifully coexist on the same machine. The tool is currently in version 2.9.1 and, as the previous versions of STS, it offers a good set of features for integrating with Grails. After the installation is completed I suggest to open the Dashboard and select the tab "Extensions". If you have just installed the tool, it should look more or less like in figure 1.

Figure 1: STS 2.9.1 Dashboard right after installation.

As you can easily verify in figure1, I would suggest to pick two extensions in particular: Grails Support and Google Plugin for Eclipse - which now comes with GWT 2.4.0. Select those and proceed with the installation. I don't usually pick the "Grails (current production release)" as I usually download and install Grails separately. The current release version of Grails is 2.0.3 and you should download it and unzip it in a convenient location.

Figure 2: Setting up Grails in STS.

Once the installation is terminated, it is time to configure the plugins. The Grails Support plugin needs to know where the Grails installation is (figure 2). We can now create a new Grails project that I am going to name GwtTest.

Figure 3: Creating a new Grails project in STS 

The creation process should ask you if you want to change the perspective into the Grails perspective offered by STS. Once the project is created it is time to install the GWT Plugin for Grails.

Figure 4: Opening the Grails command prompt

You can perform this operation through the Grails command prompt offered by STS (figure 4) by typing
install-plugin gwt
And the process should complete displaying the details in the console:

Figure 5: Console after installation of the GWT plugin (0.6.1) for Grails
 
Note: Remember also to set up the GWT_HOME that is used for compilation.

We are now ready to create our first GWT module (learn about GWT modules here). Using once again the Grails command prompt offered by STS, we type:
create-gwt-module org.example.HelloApp
Once the process is completed, if you refresh the project, you will be able to notice that a new directory 'src' has appeared in the project explorer.

Figure 6: Project explorer and Console after the creation of the HelloApp GWT module

In order to declare this folder as a source code folder we can right click on the project and select 'Build Path'>'Configure Build Path' dialog. In the tab 'source' we select 'add folder' and we pick the newly created 'src/gwt' folder.

Figure 7: Declaring the GWT folder as a source code folder

We can now create the page hosting the GWT script by typing in the command prompt:
  create-gwt-page hello.gsp org.example.HelloApp
The new page will include the line of code that is performing the actual import of the GWT artifact:
<script src="${resource(dir:'gwt/org.example.HelloApp',
 file:'org.example.HelloApp.nocache.js')}" type="text/javascript">
</script>

We are now going to modify the HelloApp.java file adding Window.alert("hello"); within the method onModuleLoad() so that when the script is loading the alert 'hello' will fire.

We then compile the GWT code by typing in the command prompt:
compile-gwt-modules
And we are potentially ready to go. After running the Grails project - a simple run-app is good enough - and opening the page:
http://localhost:8080/{projectname}/hello.gsp
you will notice that nothing happens. As a matter of fact, if you check out what happens with Firebugs, you will notice that a resource has not been found. Unfortunately, it seems the Grails Resources Plugin, which is installed by default in the project, is not compatible with the Grails GWT Plugin. As suggested in this post we can modify the Config.groovy file to include:
grails.resources.adhoc.excludes = ['**/gwt/**']
When restarting the server, the hello.gsp page should now work and fire the 'hello' alert.

Wednesday, September 14, 2011

Grails 1.3.7, Spring Security and OpenID... with exception

Here is the list of steps I performed to set up OpenID authentication with Spring Security:

1) Create Project with Grails 1.3.7
grails create-project UserManagement 
The file application.properties will look something like this:
app.grails.version=1.3.7
app.name=UsersManagement
app.servlet.version=2.4
app.version=0.1
plugins.hibernate=1.3.7
plugins.tomcat=1.3.7 

2) Installing the Spring Security plugin (website and documentation)
grails install-plugin spring-security-core
The file application.properties will now look something like this:
app.grails.version=1.3.7
app.name=UsersManagement
app.servlet.version=2.4
app.version=0.1
plugins.hibernate=1.3.7
plugins.spring-security-core=1.2.1
plugins.tomcat=1.3.7

3) Creating Controller and template classes
grails s2-quickstart org.commonsemantics.scigrails.module.users.security User Role
You will notice the following new files
controllers/LoginController.groovy
controllers/LogoutController.groovy
domain/org.commonsemantics.scigrails.module.users.security.User.groovy
domain/org.commonsemantics.scigrails.module.users.security.Role.groovy
domain/org.commonsemantics.scigrails.module.users.security.UserRole.groovy
views/login/auth.gsp
views/login/denied.gsp
The Config.groovy will be updated with the following lines:
grails.plugins.springsecurity.userLookup.userDomainClassName =
      'org.commonsemantics.scigrails.module.users.security.User'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 
      'org.commonsemantics.scigrails.module.users.security.UserRole'
grails.plugins.springsecurity.authority.className = 
      'org.commonsemantics.scigrails.module.users.security.Role'
If you are going to change the package of the above classes, just remember to update the above properties.

4) Move controllers to the desired package - org.commonsemantics.scigrails.module.users.security

5) Install the OpenID module (website and documentation)
grails install-plugin spring-security-openid
The file application.properties will now look something like this:
app.grails.version=1.3.7
app.name=UsersManagement
app.servlet.version=2.4
app.version=0.1
plugins.hibernate=1.3.7
plugins.spring-security-core=1.2.1
plugins.spring-security-openid=1.0.3
plugins.tomcat=1.3.7

6) Creates OpenId Controller and templates for it.
grails s2-init-openid
This script adds the following files:
controllers/OpenIdController.groovy
views/openId/auth.gsp
views/openId/createAccount.gsp
views/openId/linkAccount.gsp

7) Move OpenIdController to the desired package - org.commonsemantics.scigrails.module.users.security

8) Add support for the remember-me checkbox
grails s2-create-persistent-token 
     org.commonsemantics.scigrails.module.users.security.PersistentLogin
It adds the file:
domain/org.commonsemantics.scigrails.module.users.security.PersistentLogin.groovy
The Config.groovy is updated with the following lines:
grails.plugins.springsecurity.rememberMe.persistent = true
grails.plugins.springsecurity.rememberMe.persistentToken.domainClassName =
     'org.commonsemantics.scigrails.module.users.security.PersistentLogin'
Once again, if you are going to change the package of the above classe, just remember to update the correspontend property.

9) Creating the OpenID domain class
grails s2-create-openid 
     org.commonsemantics.scigrails.module.users.security.OpenID 
The script creates on file:
domain/org.commonsemantics.scigrails.module.users.security.OpenID.groovy
The Config.groovy is updated with the following line:
grails.plugins.springsecurity.openid.domainClass =       
     'org.commonsemantics.scigrails.module.users.security.OpenID'
Once again, if you are going to change the package of the above classe, just remember to update the correspontend property.

10) Adding OpenIDs to the User domain class

The following line of code has to be added to the existing User.groovy class:
static hasMany = [openIds: OpenID]

11) Creating some test users

As suggested by the documentation we can now create some test users by editing the Bootstrap.groovy file as follows
import org.commonsemantics.scigrails.module.users.security.Role
import org.commonsemantics.scigrails.module.users.security.User
import org.commonsemantics.scigrails.module.users.security.UserRole

class BootStrap {

    def springSecurityService

    def init = { servletContext -> 

        String password = springSecurityService.encodePassword('password')
        
        def roleAdmin = new Role(authority: 'ROLE_ADMIN').save() 
        def roleUser = new Role(authority: 'ROLE_USER').save()

        def user = new User(username: 'user', 
            password: password, enabled: true).save() 
        def admin = new User(username: 'admin', 
            password: password, enabled: true).save()

        UserRole.create user, roleUser 
        UserRole.create admin, roleUser 
        UserRole.create admin, roleAdmin, true 
    } 
}


12) Redirect the login requests

It is now necessary to direct the authentication calls to the new Controller that manages also the OpenIDs. We can add to the UrlMappings.groovy file the following:
"/login/auth" {
         controller = 'openId'
         action = 'auth'
      }
      "/login/openIdCreateAccount" {
         controller = 'openId'
         action = 'createAccount'
      }

13) Running Grails and testing
grails run-app 
Welcome to Grails 1.3.7 - http://grails.org/
Licensed under Apache Standard License 2.0
...
...
Configuring Spring Security ...
Configuring Spring Security OpenID ...
Server running. Browse to http://localhost:8080/UsersManagement

When accessing the page you should see something like this:
I will try it yourself but the authentication did not work for me right away. I logged in with my Google OpenID and I got sent to the screen for creating an account.
I then selected the 'link this OpenID' option.
After introducing the testing credential 'user' and 'password' I got a 'user not found' back.

14) Turning on the logging

First thing I wanted to see if there were any weird things happening by turning on the logging in the Config.groovy file:
debug 'org.springframework.security'
No exceptions emerged when repeating the process.

15) Making sure the User is stored in the DB

We can inspect the default HSQLDB by adding at the end of Bootstrap.groovy init the following:
org.hsqldb.util.DatabaseManager.main()'
this will open the in memory database inspector. Just remember that if you close the inspector that will also shutdown your Grails app. Read more about the inspector here and remember to take out that line once the debugging is done..

The users resulted stored in the database.

16) Making sure the encoding process works correctly

After editing the Bootstrap.groovy file with:
String password = springSecurityService.encodePassword('password')
println 'a ' + password
def admin = new User(username: 'admin', password: password, 
     enabled: true).save(failOnError: true)
println 'b ' + User.findByUsername('admin').password
and a restart, I obtained:
a 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
b 113459eb7bb31bddee85ade5230d6ad5d8b2fb52879e00a84ff6ae1067a210d3

It is clear that the login process is not performing correctly. After investigating I found out that the User domain class includes the methods:
def beforeInsert() {
          encodePassword()
     }

     def beforeUpdate() {
          if (isDirty('password')) {
                encodePassword()
          }
     }

17) Updating the Bootstrap.groovy file

As the User domain class is already performing the encoding, we have to edit the Bootstrap.groovy file line:
String password = springSecurityService.encodePassword('password')
Into
String password = 'password'

And now the login process works for me. We can now remove org.hsqldb.util.DatabaseManager.main() from the end of the Bootstrap.groovy and maybe comment out the logging (see point #14).

18) Remove the unused views and controllers?

It is not possible to remove any of the generated controllers. As far as I know the only file that can be removed is
views/login/auth.gsp
as the new auth.gsp file provided by the OpenID plugin is now in use (see point #12).


You can check out the code as follows:
svn checkout 
     https://common-semantics.googlecode.com/svn/tags/UsersManagement20110914  
     UsersManagement

Resources
OpenID website
Spring Security Plugin for Grails website
OpenID Plugin for Spring Security website