Tuesday, 1 May 2012

ZK Grails + MVVM

The 6.0 release of ZK introduced the MVVM pattern and they have been fairly well documented in their website. Using the new pattern with zkgrails is another story. Its major attraction to me is that it is farily easy to unit test a ViewModel, compared to testing a Composer(has anyone been able to do this?). I decided delved into it today and figured that the best way to do it was to start a brand new project and try different things. In the end, I did the hard way first and later found out a rather easier way. So, without further ado, here we go.

The source code for the sample app can be found on github. I won't explain how to install grails and the zkgrails plugin. The domain class Person is shown here: First I needed a form to create persons, so I created the corresponding zul: create-zul com.example.create This creates a zul under grails-app/zul The corresponding view model was also created: create-viewmodel com.example.Person A PersonViewModel.groovy was added to grails-app/viewmodels/com/example/ ZK has some issues keeping hibernate sessions, so as a work around, zkgrails has facades. We will use a PersonFacade to interact with GORM: The test for the PersonViewModel: And finally our PersonViewModel: A couple things to point out before we continue.
  1. @WireVariable is needed to wire a spring bean. All facades created by zkgrails are spring beans, so we need this annotation to wire it.
  2. @NotifyChange is used to notify the corresponding variables of any changes.
  3. @Command is the equivalent of an onCLick_ method. This can be used to bind an event in the UI to a method in the ViewModel.
  4. A custom validtor to ensure that the first name is added.
The corresponding zul: ZKgrails has a script caleld create-zul-viewmodel, that creates a zul template an ViewModel. However, I didn't know about this script, so I created them separately. If you do it this way, then you have to modify the composer to extend org.zkoss.bind.BindComposer instead of GrailsForwardComposer. I wasted hours before I figured this one out. Then a view model has to be assigned to the component. This requires the following assignments:
  • @id('vm') : this assigns viewmodel to a variable(vm) allowing us to access it throughout our view.
  • @init('com.example.PersonViewModel') : assigns an instance of this class to vm.
  • validationMessages="@id('vmsgs')" : all validation messages from our custom validators can be accessed with this variable(vmsgs).
There is also a label that simulates a flash message. This is bound to a variable in the viewmodel called successFlash: @load(vm.successFlash). This will assign a value to the label that corresponds to the successFlash proeprty in PersonViewModel. Each of the elements of the form are bound to the viewmodel also. In this example, the values for a person are stored in map. For example: @bind(vm.person.firstName) For custom validators we have an additional annotation : @save(vm.person.firstName, before='save') @validator(vm.firstNameValidator) This is saying that before the command 'save' is executed, we should run firstNameValidator() on person.firstName. If there are any errors, we can access those errors with the perviously declared vmsgs. In this example, it is being loaded from viewmodel and displayed in a label:
<label value="@load(vmsgs[firstNameTextbox])" style="color:red;"/>

Finally, we have to tell the form what to do when its submitted. This is done by assigning a 'command' to a button:
<button id="createButton" label="Create" onClick="@command('save'))" />

To view the form you can go to http://localhost:8080/com/example/create.zul Now, the right way to create the view model and the corresponding zul is as follows:

create-zul-viewmodel

This will create a zul and a corresponding view model wired together, without the need to have the composer extend BindComposer: That's it. The surface of MVVM in zkgrails.

Tuesday, 18 October 2011

SVN: Merge Branch to Trunk

We are still using subversion instead of git, hopefully someday we can migrate. In the meantime I still struggle with some of the basics. From now on I will at least know to check this blog whenever I want to merge. The following method assumes no development is done on trunk, only branches are merged to it once a new release is ready.

First, we need to make sure we have all our changes in our working copy checked in before we proceed. Then we check out the trunk and switch to it:  
svn co http://server/repository/project/trunk 
svn switch http://server/repository/project/trunk 

Now we can merge:  
svn merge http://server/repository/project/trunk http://server/repository/project/branches/MyBranch 

Finally we can commit to the server:
svn ci -m "Merge MyBranch to Trunk"

Finished. :)

Thursday, 15 September 2011

REST + Griffon + Grails

Okay, it has been quite a while since my last post, but I'm back. Hopefully I can post more regularly.
So, this is what I've been up to. I want to be able to expose my grails api using REST, but want to do it in a secure manner. The basic idea is that I can develop desktop apps, web apps, mobile apps, etc, and they all use the api from a central server to persist and get data.

For the moment, I'm using grails 1.3.7 and the Nimble plugin for authentication. Nimble is based on shiro and I really like it. Once it is installed, I had to add the following to Config.groovy:

 security{
shiro{
authc.required=false
filter.config="""\
[filters]
#HTTP Basic Authentication
authcBasic = org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
authcBasic.applicationName = Rest_Auth
[urls]
/author/**=authcBasic
"""
}
}


So here we are telling grails to use the specified filter to authenticate any request made to the given url. So if a user needs to access anything under author, they need to authenticate. Now, the javadoc for BasicHttpAuthenticationFilter says the following:


Requires the requesting user to be authenticated for the request to continue, and if they're not, requires the user to login via the HTTP Basic protocol-specific challenge. Upon successful login, they're allowed to continue on to the requested resource/url.
This implementation is a 'clean room' Java implementation of Basic HTTP Authentication specification per RFC 2617.
Basic authentication functions as follows:
  1. A request comes in for a resource that requires authentication.
  2. The server replies with a 401 response status, sets the WWW-Authenticate header, and the contents of a page informing the user that the incoming resource requires authentication.
  3. Upon receiving this WWW-Authenticate challenge from the server, the client then takes a username and a password and puts them in the following format:username:password
  4. This token is then base 64 encoded.
  5. The client then sends another request for the same resource with the following header:Authorization: Basic Base64_encoded_username_and_password




    So now our grails app requires that any requests to author be authenticated. Now, in our griffon app, we installed the rest plugin: griffon install-plugin rest.


    The documentation for the plugin is not all that good, or maybe I'm too dumb. So I had to figure things out on my own. I found out that it actually makes extensive use of HttpBuilder : http://groovy.codehaus.org/modules/http-builder/doc

    The rest plugin creates an instance of RESTClient, which in turn inherits from HttpBuilder, and guess what? HttpBuilder has a property auth.basic .Here we can specify the username and password and HttpBuilder will send that to the grails application whenever authentication is required. Here is a sample of how it would be done with griffon:

    withRest(id:'sampleId', uri: 'http://localhost:8080/myapp'){

    auth.basic 'username', 'password' 

    def response = get(path: 'author')

    //Do something with the response 



    }


    Caution, the password is send in clear, so just make sure you use https. 

Thursday, 7 July 2011

Nimble : Permissions, Groups & Roles

The documentation for nimble is not really all that good, however, the plugin is amazing. I feel lazy switching to spring security, so for the moment I'm sticking with nimble/shiro.

So I needed to create some default permissions, groups and roles in my application and it was taking me some time to figure out how to do this. What I had to do was to edit grails-app/conf/NimbleBootStrap.groovy and add them like this:

def adminOfficerRole = roleService.createRole('ADMIN_OFFICER','Administrative Offficers', false)
def basicMgmtGroup = groupService.createGroup('BASIC_MGMT','Group that does basic management',false)
roleService.addGroupMemeber(basicMgmtGroup,adminOfficerRole)

LevelPermission perm = new LevelPermission()
perm.populate('controller1,controller2','*',null,null,null,null)
perm.managed=false
permissionService.createPermission(perm,basicMgmtGroup)

//Add a user to a role
roleService.addMember(UserBase.findByUsername('username'),adminOfficerRole)

In our controllers we can now check for permissions as follows:

if(SecurityUtils.getSubject().isPermitted("controller:action")){
//DO SOMETHING HERE
}

Whew! Okay, now I shouldn't forget. :D

Radioactivo 98.5

While I was studying in Mexico from 1996 to 2002, my favourite radio station was Radioactivo 98.5 . It was closed down in 2002, but it left its mark in the Mexican Radiostation landscape. So when I found a link where I could listen to it once more I was delighted. It is more like a retrospective radiostation. Anyways, here is the link:

Wednesday, 6 July 2011

Intro

Okay, this is my first attempt at blogging. Have so many things on my mind, decided that maybe this is a good way to track and record them.