Defining load order and dependencies to your grails plugins 0

Hello all,

I’m buiding a simple Grails Plugin that will use GORM dynamic finders and methods, but as we should know, the create-plugin grails command just install a fresh skeleton of your grails application, without any other dependencies.

First of all, you shoud install the hibernate plugin inside your plugin. Don’t worry, the hibernate will not be packaged with your plugin, but will be there to your plugin classes use.

grails install-plugin hibernate

So, now your plugin have the hibernate plugin installed and will be capable to use GORM facilities. But, if people wants to use your plugin, they will have to have hibernate plugin installed, correct? I know it cames by default in our grails application, but can be uninstalled. So we have to find some way to make our plugin dependent on hibernate plugin. Asking on the grails-user list and reading this topic in grails.org wiki, I remembered on two plugin configurations that can help us:

  • dependsOn
  • loadAfter

The dependsOn it’s a map inside our XptoGrailsPlugin that tells witch plugins our one depends, it takes the name of the respective plugin and its version, in my case, that’s what I did:

def dependsOn = ["hibernate":"1.1 > *"]

So, our plugin will depend on grails hibernate plugin, and at least the 1.1 version of it, none previous will be accepted and any future ones will be ok!

But sometimes this is not enougth, besides being dependent, our plugin uses dynamic finders, and runtime added method on our domain classes, so, it’ll only be successfully loaded after hibernate plugin load and adds this methods. To achieve this, we’ll use the other tag, the loadAfter to tell that our plugin will wait hibernate plugin to be loaded and the load itself.

def loadAfter = ['hibernate']

That’s it. Doing this we’ll make things work as we wanted.

PS.: just noticed, right now that Graeme Rocher pushed to github’s grails master branch, a commit that will install de default plugins into new plugin projetcs too. This sounds cool, and will avoid us the first step above, the plugin installation. Here is the commit id and link: 9cb23f5b835b633cf43079ca7e58e29c64bd3b3c

Changing the default locale for your grails application 6

Thank god grails has a wonderful i18n native support. It’s great change all your application language just by setting one more parameter in the URL (lang). If you do not know this behaviour, check this out.

But sometimes you have to preset the default language because not all your applications will be in english, yap ? To make this you’ll have to set your localeResolver in your resources.groovy spring configuration file. just add this code to it. (note that my code is setting my language to brazilian portuguese – pt_BR)

//this is your resources.groovy file
//
beans = {
   localeResolver(org.springframework.web.servlet.i18n.SessionLocaleResolver) {
      defaultLocale = new Locale("pt","BR")
      java.util.Locale.setDefault(defaultLocale)
   }
}

[4/25] Jasper Reports in Grails with Dynamic-Jasper 9

This tutorial will talk about producing Jasper PDF reports (or any other format you’d like) in you grails app.  I took a look in grails plugins portal I found two plugins that could be used to do this.  The Jasper Plugin and the DynamicJasper Plugin. Depending on what you really need you’ll choose one.

I see the JasperPlugin as a more customizable plugin since you’ll use it o link to an existing jasper report (.jrxml / .jasper) you have. You’ll have some work building it, modeling it and sometimes even “drawing” it, but if you really need to do your and just your jasper, I recommend this one (congratulations for the Brazilians responsible for this plugin).

Otherwise (and covered in this tutorial), if you just need a simple report for your domain classes (an poor-but-effective PDF view of your scaffold listing) like I need in one project here, the DynamicJasper Plugin is gonna let you rock!

It’s a simple, and versatile plugin that generate its output entirely dynamic. This means that you won’t need to open iReport and show us your drawing skills (as a good programmer, you may suck drawing!).

We’ll work only with the Entities Report that Dynamic Jasper offer us, if you need complex queries on the reports, I recommend you reading the “named reports” in the plugins official documentation.

Are you following me and reading my blog’s feed? Be the first to know when I publish some interesting article signing up to my feed and following me on twitter!

Tutorial Info

Groovy Version: 1.6
Grails Version: 1.1
Plugin Version: 0.5
Plugin Documentation: http://grails.org/plugin/dynamic-jasper
Download: source code

Basic setup

Well, our example this time will be a simple agenda, so, let’s create our agenda app, install the dynamic jasper plugin and then create our domain class with some constraints.

grails create-app agenda
grails install-plugin dynamic-jasper
grails create-domain-class Contact

Our initial Contact class will be this one

class Contact {
   String name
   String nickname
   Date bornAt
   String email
   String website
   String phone
   String mobilePhone
   String gender

   static constraints = {
      name(maxLength: 255)
      nickname(nullable: true)
      bornAt(nullable:true)
      email(email:true)
      website(link:true, nullable:true)
      phone()
      mobilePhone()
      gender(inList:["M","F"])
   }
}

Running the application and making it reportable

That’s it, you can run your application and test it if you want. Now we’re going to create our first report, the simplest one we can have. To do this just add this code to your domain class:

static def reportable = [:]

This map notation will tell what fields will be shown in the report and what options of it you’re configuring. As we do not specified any, all propeties will be there and the default report will be generated.

After this you can visit the report generator url at http://localhost:8080/agenda/djReport/index?entity=contact and this will generate a simple report file (no extension, you should add .pdf) of your contacts.

Very very simple, hã!

More options (personalization)

Now let’s configure some basic options of our report. First of all, I’ll not get all this properties in our agenda report, let’s get only the main fields (nick, phone, email):

def static reportable = [
   columns: ['nickname', 'email', 'phone']
]

You can run again the report, it will be similar to this one:

report

Now, there are some other basic options you might want to configure, like the filename, the report title and other stuff:

title: The report’s title, by default if you do not set anything it will be “[entity-name] report”.
fileName: The name that the response file generated will have
columns: the columns shown

def static reportable = [
   title: 'My agenda',
   fileName: 'agenda',
   columns: ['nickname', 'email', 'phone']
]

Second report

This three will help you start in this great plugin. Take a look in the plugin’s page to see all you can do.

It’s a simple but powerful plugin, you can adjust all the page layout, group properties, change the column titles, everything that does not involve the usual iReport drawing process.

Important Note

This note may be valid to other plugins either, but since grails 1.1, the installed plugins is not available in the project’s folder but in your HOME_DIR/.grails/1.1/projects/<project>/plugins

So, if you want to use advanced configuration of this (and others) plugin, you shoud enter its folder in ~/.grails/1.1/projects/agenda/plugins/, and get the configuration file of it, (in our case, DynamicJasperConfig.groovy) in its conf folder and save in our agenda/conf folder.

This file holds all plugin configuration and it can be used to setup the report layout and configure the named reports I said before.

Again, take a look in the plugin page and you’ll find everything you need! This is just an introduction of the plugin!

[]s,

Are you following me and reading my blog’s feed? Be the first to know when I publish some interesting article signing up to my feed and following me on twitter!

[3/25] Building a RSS Reader with Quartz Plugin – Grails Tutorial 4

Are you reading my blog’s feed? Be the first to know when I publish some interesting article signing up to my feed and following me on twitter!

 

Groovy Version: 1.6
Grails Version: 1.1
Plugin Version: 0.4.1-SNAPSHOT
Plugin Docs: http://grails.org/plugin/quartz
Download Resources: source code screencast 1 screencast 2

Hello,

In this tutorial, we’ll talk about the Quartz plugin used to schedule jobs executions in your application. The plugin is build on top of the Quartz Job Scheduler Library from OpenSymphony. OpenSympony is the company that built the WebWork framework, that is now called Struts2 after Apache “aquisition”.

“Scheduling jobs” is very useful in your application to cover background needs. Some tasks you’ll need to execute undercover your application some times (invalidating old users that have not logged for more than 1 month) or even async processes that you’ll have to do if you do not have a JMS infrastructure, for example, sending e-mails to a lot of people.

In our example, we’ll build a simple RSS Reader that will use the quartz plugin to schedule fetchs it will be done in the feeds and insert in the database. Our application will mainly have one domain class called Post (seen in the last tutorial), a Feed domain class to store our feeds and a similar RSS Parser from technorati.  (Yes, I love the RSS format).

Initially, we’ll create the app, install the quartz plugin, create the domain classes and the Feed scaffold structure

grails create-app feedreader
cd feedreader
grails install-plugin quartz
grails create-domain-class Post

We’ll insert the Post domain class code

class Post {
    String title
    String link
    String body
}

We have to create the Feed domain class and its scaffold structure.

grails create-domain-class Feed
class Feed {
    String word
    String url
}

Scaffolding…

grails generate-all Feed

screencast-1
screencast

After this, we’ll create our Technorati Feed Parser from this code above.

class TechnoratiService {
    boolean transactional = false
    def parseAndSave(rss) {
        def rssObj = new XmlSlurper().parse(rss)
        rssObj.channel.item.each {
            def post = new Post(title: it.title.toString(),
                    link: it.link.toString(),
                    body: it.description.toString())
            post.save()
            println "Post [${post}] saved."
        }
    }
}

We’ll run our application using the grails run-app command and insert some feeds. Note that we’ve configured our datasource to use hsqldb storing in the filesystem instead of regular memory setup. 

Note that we have one JobController that Quartz install for us, forget about it, ok? We’ll create our own job after the second screencast.

screencast-2
screencast

Now, we have to understant some quartz properties and commands. 

When we install the quatz plugin, it installs another command for us the grails create-job MyJob, with it we’ll create our FeedParserJob. Note that we use convention over configuration with all jobs having *Job names. 

grails create-job FeedParser

Job classes have to implement the execute() method. This method is the one that Quartz will trigger when it’s time to execute the job. To define when the job it will be executed and what’s the interval between executions, I suggest you read the plugin documentation witch shows N ways to do this. In our example we’ll use a cron expression similar to *N*X OS systems setting our job to execute once in five minutes.

Our cron expression will be like this:  “0 0/5 * * * ?”

Depending on your jobs requisites, it may run concurrently with another instance of it or not. In our case, we’ll not start other job execution if the last on is still running. To prevent this behavior, we can set the concurrent property to false

def concurrent = false

Our job will essentially look for the feeds we’ve inserted on the database, and for each one it will call the Technorati service asking for new Posts. The final source for our job is the one below:

class FeedParserJob {
    def concurrent = false
    def cronExpression = "0 0/5 * * * ?"
    
    def technoratiService

    def execute() {
        def feedList = Feed.findAll()
        for (Feed feed : feedList) {
            println "Reading feed ${feed.word} @ ${feed.url}"
            technoratiService.parseAndSave(feed.url)
        }
    }
}

As you can see in the example above, you can inject any spring bean in your job, just declare it as I did with my TechnoratiService! :) (this is really great!)

That’s it, if you run you application you’ll see that every 5 minutes (minutes 0,5,10,15…) the job will be called and every posts technorati returns will be inserted on your database. Note that in this simple example we did not check if the post had been already inserted in the database before inserting it, this will just grow our database with a lot of instances representing the same post. This can be avoided checking if the post already exists before inserting it  (just check if you have any Post with the same link), but I’ll left this for you!

Before finish this, let’s just improve a little bit our post list view.

 

Tela de posts

 

 

Now, try to enrich its interface, adding some ajax to get only the new posts since the last fech! Maybe you can start from this your new Google Reader killer! :P

Now, let me know, are you using this plugin in your production environment? What for? What kind of jobs you do with it? 

Thanks!

Are you reading my blog’s feed? Be the first to know when I publish some interesting article signing up to my feed and following me on twitter!

 

Next tutorial: [4of25] Jasper Plugin

Past tutorials:
        [2of25] Searchable Plugin
        [1of25] AcegiSecurity Plugin

[1/25] Acegi: Secure your grails application with no pain 36

Groovy Version: 1.6
Grails Version: 1.1
Plugin Version: 0.5.1
Plugin Docs: http://grails.org/plugin/acegi
Tutorial resources: Download here

Tutorial topics

  1. Overview
  2. Download and install
  3. Domain classes
  4. Permissions Management
  5. Storing permissions outside the database
  6. User self registration
  7. Taglib and service
  8. Acegi events
  9. Conclusion

I have to thank a lot Rob James that helped me a lot in correcting some english issues and clarifying some things in my head. Specially in the Roles/Authentication part, witch was rewrited by him.

Overview

The Acegi Security plugin provides an easy way to work with Spring Sercurity. I really like this plugin ’cause after it is installed, it is ready to be used. Offering user authentication, registration and management out-of-the box. I’m using this plugin in some of my projects and for what I need, it’s awesome. Here are some of the features I really like in it:

  • User management
  • Online permissions (roles x uri) management when storing in a database (you can also store this in the config file)
  • A simple registration screen, protected with a simple captcha and support for mailing user’s their credentials
  • Login/logout with no pain
  • Quick OpenID and LDAP integration
  • User-chosen domain class names
  • Simple taglib and service class for integration your application

.

Download and install

To install the Acegi Security plugin, we’ll create a simple app called “tutorials” in witch I’ll start the plugin tutorials.

grails create-app tutorials

As any other plugin, we can choose from a remote install where the files will be fetched from the official grails plugins repository (http://plugins.grails.org) or from a local install, where you can install from a local zip file. I’ll demonstrate both.

Remote install

grails install-plugin acegi

The main advantage on getting it from the remote repository is that you’ll always get the latest plugin version.

Local install

grails install-plugin /Users/lucastex/grails/plugins/acegi/grails-acegi-0.5.1.zip

I like installing the plugins from my local repository because I’m not online all the time, sometimes I’m behind a nasty proxy and this way I can have previous versions of the plugin in case I need to get to them. Since plugin zip files are really tiny, I recommend you storing it in some old usb flash memory or in any webdav drive over the cloud… :)

After installing it, you’ll get all dependencies you need for using the plugin features (except for the mail.jar and activation.jar that will be downloaded only when needed).

The process is shown here:

thumb

Domain Classes

Authentication and Authorization firstly involves understanding some important concepts.

Who can do what?

A “User” in Acegi is a login, which represents an individual person. This User will log into your application, and will consequently have certain functions that they can perform. With Acegi, you are firstly permitting users access to your application (Authentication) and secondly determining if they can perform a certain function (Authorization).

If we were to try and map this to the physical world, you could draw an analogy with how people work in an organisation. In your company, people are “Authenticated” to get into the building with an Identification card. It confirms that the person is who they claim to be. With Acegi, we generally do this with a Username and Password (although this the main way to authenticate in Acegi, there are actual many different ways of doing this).

Once in the building, they may be “Authorized” to do certain things. These authorizations prevent the Mailroom Clerk from signing off on a $1 billion project that the CEO must do. And therefore the Mailroom Clerk may be “authorized” to do or access less things than the CEO is.

In Acegi, we do this by assigning users to certain “Roles”. Roles can be confusing at times, because they are actually quite flexible. In its simplest form, you can create Roles that represent real world Roles, such as Admin, Developer, Clerk, Manager. Then in your application, you can test if the Authorized user has that role before allowing them to perform a certain function.

A more powerful model is to break down the “functions” they can perform as roles. This will allow for more flexibility in the long term. For example, all your users may have basic access to information, but only Admins, Managers and Developers have access to Documents, and Managers and Admins can modify this information, and finally Admins will be the only role that can create users. So you can create Roles in Acegi like, “PROJECT_ACCESS”, “USER_ACCESS”, “USER_WRITE” etc.

The power in doing this, is that you can have users (individuals) sharing responsibilities without changing a line of code. So you can decide that Developers can now modify documents, and just assign them that Role.

The process of “Assigning” Roles (the Authorities) to Users (the Authentication) is done through the RequestMap entity (default by the AcegiSerurity).

With these fresh concepts, we can now create these entities inside our application using one command the plugin installed for us, the “create-auth-class” command. The command itself creates all the 3 classes we need, but we’ll pass the names of the Domain objects we want each class to have as arguments. The regular usage for it is:

grails create-auth-domains &lt;person class name&gt; &lt;authority class name&gt; &lt;request map class name&gt;

And our command consists of:

grails create-auth-domains User Role RequestMap

After this, we get some new files in the project:

Login user domain class: User
Authority domain class: Role
Requestmap domain class: RequestMap
file generated at /home/lucastex/Desktop/grails/tutorials/grails-app/domain/User.groovy
file generated at /home/lucastex/Desktop/grails/tutorials/grails-app/domain/Role.groovy
file generated at /home/lucastex/Desktop/grails/tutorials/grails-app/domain/RequestMap.groovy
file generated at /home/lucastex/Desktop/grails/tutorials/grails-app/conf/SecurityConfig.groovy
copying login.gsp and Login/Logout Controller example.
[mkdir] Created dir: /home/lucastex/Desktop/grails/tutorials/grails-app/views/login
[copy] Copying 1 file to /home/lucastex/Desktop/grails/tutorials/grails-app/views/login
[copy] Copying 1 file to /home/lucastex/Desktop/grails/tutorials/grails-app/views/login
[copy] Copying 1 file to /home/lucastex/Desktop/grails/tutorials/grails-app/views/login
[copy] Copying 1 file to /home/lucastex/Desktop/grails/tutorials/grails-app/controllers
[copy] Copying 1 file to /home/lucastex/Desktop/grails/tutorials/grails-app/controllers

If we run the application, we’ll notice that we have one logincontroller and one logoutcontroller, they are ready to be used and all we have to do is setup one user in the database. Due to the laziness that is consuming me right now, to create and manage the users, we’ll run the second command the plugin gives us.

grails generate-manager

After running it, we’ll have more controllers (that manage the users, roles and requestmaps) and all the necessary views.
Using the new controllers, we’ll add two new roles, one admin user (god) and one other user with simple user privileges (slave).

That’s it, you can now use the login and logout controller to test the process!

thumb

Permissions Management

Keep in mind that securing URLs is not easy. You have to think what actions are linked with what “flows” in your web app and draw from the permission graphs, linking profiles (roles) with actions. Be calm, after the first one, you’ll be the master of roles.
You’ll use the RequestMapController to do this. Access this screen by clicking on the RequestMapController link and take a look at your options. In the field labeled as “URL”, you’ll enter the URL you want to secure, and below it, you’ll enter the roles you want to grant access to it, for example, in our app, we’ll restrict the user creation process, so only admin users logged should create users.

URL: /user/create
Roles: ROLE_ADMIN

Doing this, only admins will have access to create new users in the app.

And we’ll let any logged in user list users, but non-logged users won’t do this:

URL: /user/list
Roles: ROLE_ADMIN, ROLE_USER

Take a look in this quick presentation, showing the users trying to log and execute the actions. Note that the “safari” user will be the admin user, and the “firefox” user will be the regular user. And note that the rest of actions/controllers (RoleController, RequestMapController) are not affected.

thumb

That’s it! As this tutorial is using the in-memory database grails offer us, let’s edit our BootStrap.groovy file so we can load some sample data (so that we don’t have to manually keep doing this). Note that I’ll secure other actions here as well.

Adding Roles:

//Adding Roles
def roleAdmin = new Role(authority:'ROLE_ADMIN', description:'App admin').save()
def roleUser  = new Role(authority:'ROLE_USER', description:'App user').save()

Adding Users:

http://snipplr.com/view/13209/adding-users-to-bootstrapgroovy/

Adding Permissions:

//Adding Users
def userGod = new User( username:'god',
userRealName:'god almighty',
enabled: true,
emailShow: true,
email: 'god@grailsapp.com',
passwd: authenticateService.encodePassword('god')).save()

def userSlave = new User(username:'slave',
userRealName:'poor slave',
enabled: true,
emailShow: true,
email: 'slave@grailsapp.com',
passwd: authenticateService.encodePassword('slave')).save()

Final Bootstrap.groovy:

class BootStrap {

def authenticateService

def init = { servletContext -&gt;

//Adding Roles
def roleAdmin = new Role(authority:'ROLE_ADMIN', description:'App admin').save()
def roleUser  = new Role(authority:'ROLE_USER', description:'App user').save()

//Adding Users
def userGod = new User(username:'god',
userRealName:'god almighty',
enabled: true,
emailShow: true,
email: 'god@grailsapp.com',
passwd: authenticateService.encodePassword('god')).save()

def userSlave = new User(    username:'slave',
userRealName:'poor slave',
enabled: true,
emailShow: true,
email: 'slave@grailsapp.com',
passwd: authenticateService.encodePassword('slave')).save()

def secureUserEdit = new RequestMap(url: '/user/edit', configAttribute:'ROLE_ADMIN').save()
def secureUserSave = new RequestMap(url: '/user/save', configAttribute:'ROLE_ADMIN').save()
def secureUserCreate = new RequestMap(url: '/user/create', configAttribute:'ROLE_ADMIN').save()

def secureUserList = new RequestMap(url: '/user/list', configAttribute:'ROLE_ADMIN, ROLE_USER').save()

//Note that here we associate users with their respective roles
roleAdmin.addToPeople(userGod)
roleUser.addToPeople(userGod)
roleUser.addToPeople(userSlave)

}
def destroy = {
}
}

Storing permissions outside the database

Depending on your application needs, it may be better to store all permissions (requestmaps) outside the database. It’s up to you.

database

* Pros: You can change permissions on the fly! new permissions to old roles can be assigned in the RequestMap Domain we’ve created and after its added, it s working without a restart of the application.
* Cons: All requests will have to search for the requestmap permissions inside its objects. Upgrading these objects to memory will cost in database round trips, but won’t be terrible.

securityconfig

* Pros: It’s faster! If your site relies on performance and you don’t expect dynamically having to secure new URLs at runtime, this is for you :P
* Cons: You will have to restart your applications when the permissions changes.

If permissions don’t change often, I strongly recommend you store all permissions outside the database, but remember.. It’s up to you and what your application needs! :)

Let’s take our tutorials app and change the permissions mapping to the static method. First of all, I’ll comment the lines on our BootStrap to not insert the permissions we did, and then, open the tutorials/grails-app/conf/SecurityConfig.groovy file. We’ll see:

security {

// see DefaultSecurityConfig.groovy for all settable/overridable properties

active = true

loginUserDomainClass = "User"
authorityDomainClass = "Role"
requestMapClass = "RequestMap"
}

Three important points:

* Note that our domain class names are written there, so please DO NOT change this. This will mess up with your application :P
* The DefaultSecurityConfig.groovy defines everything in Acegi’s behavior, so take a look in this file, it’s important to understand what can be done! :P
* Read this doc where all is explained about what you’ll find inside the DefaultSecurityConfig.groovy

Now, we’ll add the same permissions we’ve added before using the BootStrap, but this time in the DefaultSecurityConfig.groovy file. In a string called requestMapString, set the variable useRequestMapDomainClass to false, so the application will not use the domain class we’ve created. Pay attention to the simple syntax, using URL=ROLE1,ROLE2,….

All these changes result in this SecurityConfig.groovy

security {

// see DefaultSecurityConfig.groovy for all settable/overridable properties

active = true

loginUserDomainClass = "User"
authorityDomainClass = "Role"
requestMapClass = "RequestMap"

useRequestMapDomainClass = false

requestMapString = """
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/user/create=ROLE_ADMIN
/user/edit=ROLE_ADMIN
/user/save=ROLE_ADMIN
/user/list=ROLE_ADMIN, ROLE_USER
"""
}

User self registration

The acegi plugin also gives us another command-line tool, that auto-generate a simple registration screen that you can use for visitors to register themselves in your app. It’s a simple form, with password confirmation and even a simple captcha! I’m using it in my own project and it works great. To generate this, all you have to do is run this command line inside your grails application:

grails generate-registration

Now run your application using the run-app command and you’ll see all the existing controllers as well as a brand new one, called RegisterController. This handle’s the user registration.

You can also send confirmation e-mails to users. But I won’t cover this on this tutorial. I’ll leave this to the Mail Plugin.

Important trick: It’s not correct to any user in your application to not have any roles, so you have to define one “DEFAULT ROLE” for self registrations. You can do this in the SecurityConfig.groovy, like this:

security.defaultRole = "USER_ROLE"

Taglib and service

Ok, I have a secured application, user can register and the roles are defined, but how will I integrate my existing application with all this new stuff? The Acegi Security plugin also installs two interesting resources in your application:

AuthenticateService

This service can be injected inside your application, such as your controllers and services. It provides access to the logged in user information that may be needed when, for example, your application need to log which user is logged in and posting articles!

You can inject the service like any other service you’ve created, and you may retrieve information about the user (IMO, the most important is explained here).
Logged in User’s principal: calling the method “principal()” on the service, will return you the Principal object that can give you the username and the authorities of the user.
I’ll show a simple snippet of an action using it:

def authenticateService

def debugPrincipal = {
def userPrincipal = authenticateService.principal()
println userPrincipal.getUsername() //shows the current logged user username
println userPrincipal.getAuthorities() //shows the current logged user authorities
redirect action: list, params: params
}

Just REMEMBER; If no one is logged in, the method will return the String “anonymousUser”. Be careful when trying to get the username from this String, you will get an exception.

AuthorizeTaglib

This is the taglib that you’ll use on your GSPs to interact with the plugin.

* isLoggedIn – restrict access to content within this tag to logged in users only
* isNotLoggedIn – restrict access to content within this tag to non-logged in users only
* loggedInUserInfo -this will give you information about the logged in user domain class, you pass the property name and it returns it’s value.
* ifAllGranted – restrict access to content within this tag only if the logged user have ALL THE ROLES passed to the taglib
* ifAnyGranted – restrict access to content within this tag only the logged in user has ANY of the ROLES that was passed to the taglib.
* ifNonGranted – (I think you got it!) Only will show the content if the user DOES NOT have any of these roles

&lt;g:isLoggedIn&gt;
Only logged users (no matter witch roles) will see this text. This is useful to build the "Welcome ..." text and the logout link!
&lt;/g:isLoggedIn&gt;

&lt;g:isNotLoggedIn&gt;
Only anonymous users will see this. This is nice to build your "login" or "registration" link!
&lt;/g:isNotLoggedIn&gt;

&lt;!-- Let's pretend we are logged as our 'god' user --&gt;
&lt;g:loggedInUserInfo field="username"/&gt; &lt;!-- will show 'god' --&gt;
&lt;g:loggedInUserInfo field="email"/&gt; &lt;!-- will show 'god@grailsapp.com' --&gt;
&lt;g:loggedInUserInfo field="userRealName"/&gt; &lt;!-- will show 'god almighty' --&gt;

&lt;g:ifAllGranted role="ROLE_ADMIN,ROLE_USER"&gt;
This information will be available for admins whom have the ROLE_USER associated either.
&lt;/g:ifAllGranted&gt;

&lt;g:ifAnyGranted role="ROLE_ADMIN,ROLE_USER"&gt;
This information will be available for any logged admin or user.
&lt;/g:ifAnyGranted&gt;

&lt;g:ifNotGranted role="ROLE_ADMIN"&gt;
All sessions that have the ROLE_ADMIN associated will not see this message!
&lt;/g:ifNotGranted&gt;

Acegi events

Let’s imagine you need to log every successful or unsuccessful user login in your system, or any other event that Acegi listens to. This can be done by building your own listener class that implements the ApplicationListener class. Implementing this interface will force you to define the onApplicationEvent method that will receive an ApplicationEvent instance.

Remember swing onClicks button events? This works in a similar way, you’ll have to check the class of the event using the “instanceof” and choose what events you’ll log, and what you won’t.

Here’s an example, logging any user login on our application, we’ll define this simple class:

import org.springframework.context.*
import org.springframework.security.event.authentication.*
import org.springframework.security.event.authorization.AbstractAuthorizationEvent

class AcegiEventListener implements ApplicationListener {

void onApplicationEvent(final ApplicationEvent e) {

if (e instanceof AbstractAuthenticationEvent) {

if (e instanceof AuthenticationSuccessEvent) {

println "** Attention: User ${e.source.principal.username} is logged!"
}
}
}
}

After this, we still have to register our class in the spring beans groovy file, so the application can find it (IMO, this should happen automatically with files ending in “ApplicationListener” as it happens with filters :P what do you think?).

beans = {

acegiEventListener(AcegiEventListener) {}

}

Conclusion

That’s it folks, a simple tutorial that shows how bad our world would be if we had to implement all this by ourselves. I love grails plugins and think without it all, grails development would be horible.

Acegi is one of the most complete plugins we have, and I really like it. This tutorial is much longer than I planned (and the others that will come), but I removed too much stuff I didn’t have time to write. Maybe I’ll do it other posts.

Thank you for reading this, and please spread it out!

Next tutorial will be about the Searchable Plugin

Want to be informed on blog news? Sign up for our feed and follow me on twitter!

Plugins para o GRails que eu recomendo 13

Brincando um pouco aqui com o Grails, pensando em uma aplicação “imaginária”, vi alguns plugins bem bacanas, que seriam úteis para esta e para, talvez, grande parte de aplicações por ai :) Segue 10 plugins que eu recomendo++:

  • OpenId Plugin

Se a sua aplicação não tem graaaaandes exigências e necessidades quanto a login, aproveite e utilize o mecanismo do OpenId, que descentraliza o login das aplicações. Vários sites implementam a especificação da OpenId e você pode logar em qualquer site que utilize este recurso com a openid cadastrada em qualquer um deles. Se você ainda não tem a sua, eu recomendo o serviço do MyOpenId. Uso ele e não tenho do que reclamar.

Url de documentação do plugin: http://www.grails.org/OpenID+Plugin

  • Acegi Security

Já se você tem grandes necessidades (que também dá pra implementar com o OpenId, mas fica mais chato), eu recomendo o Acegi Security Plugin, que usa o SpringSecurity por trás. É bem trivial e fácil de ser usado/configurado. Escrevi um tutorial passo-a-passo para utilizar ele no GrailsBrasil.com que está disponível neste link aqui.

Url de documentação do plugin: http://www.grails.org/AcegiSecurity+Plugin

  • Taggable

Este plugin facilita pra caramba se alguma entidade de seu sistema será “tagueável” (palavra do cão). Fornece a ‘infra-estrutura’ para adicionar e remover tags, além de contadores de tags, bem úteis para se implementar uma TagCloud.

Url de documentação do plugin: http://www.grails.org/Taggable+Plugin

  • Autocomplete e Star Rating

Estas duas funcionalidades vem em um único plugin, que traz muita, mas MUITA coisa bacana para enriquecer sua aplicação, é o RichUI Plugin (também já escrevi algo sobre ele no GrailsBrasil.com). Sinceramente, acho é o mais completo plugin na parte de interfaçe e interatividade.

Url de documentação do plugin: http://www.grails.org/RichUI+Plugin

  • RSS Feeds

Outro plugin indispensável, com ele você consegue gerar de uma maneira *bem* fácil feeds para seu site!

Url de documentação do plugin: http://www.grails.org/Feeds+Plugin

  • Avatar

Bom, denovo “para que”. Para que implementar um mecanismo de upload, de avatares para seu site, se hoje um dos sites que está em evidência por aí é o gravatar? Este site é bem banaca, e você vincula ao seu e-mail sua foto e pronto! Quando você entrar em um site “compliant” com o gravatar (com este plugin seu sistema se torna), os avatares simplesmente “aparecem” com o uso de uma simples taglib!

Url de documentação do plugin: http://www.grails.org/Avatar+Plugin

  • Mail

Um jeito muito fácil de se enviar e-mails. Disponível através de uma closure simples ou via service!

Url de documentação do plugin: http://www.grails.org/Mail+Plugin

  • JMS

Se você quer escalar a sua aplicação, se quiser se tornar o próximo twitter, não esqueça da “assincronidade” (irmã da taguear). Processos pesados/lentos como envio de emails, ou posts remotos (twitter por exemplo), devem ser feitos de forma assíncrona, garantindo que o usuário não pague o preço de uma instabilidade no sistema dependente!

Url de documentação do plugin: http://www.grails.org/JMS+Plugin

  • Twitter

Ahhhh o twitter, simplesmente twiitter! De um tempo pra cá me apaixonei por esse site e pela dinamicidade e interatividade dele. Então que tal um belo mashup do seu novo site/sistema com o twitter? Afinal, quer um jeito mais bacana de seus followers saberem que você tem novidades?

Url de documentação do plugin: http://www.grails.org/Twitter+Plugin

  • Commentable

Este também é bem bacana (foi colocado esta semana (junto com o Taggable) pelo Greame Rocher no repositório). Permite de uma forma muito simples, adicionar comentários a suas entidades, seja qual for ela, basta ativar o método .addComment(usuarioQueComentou, comentario). Bem legal, vale a pena para começar.

Url de documentação do plugin: http://grails.org/Commentable+Plugin

A lista completa de plugins pode ser vista aqui.

E você, quais plugins você usa? Quais você recomenda?

Construindo um serviço síncrono-assíncrono – parte 2: Aplicação Legada 0

Bom, como já disse, não gosto muito de chamar de “legadas” as aplicações que serão ativadas pelo BUS em um arquitetura SOA. A não ser é claro, que realmente façam jus a este nome. O que não gosto é de construir uma nova aplicação que conterá realmente a lógica de negócio do zero, e ainda chamá-la de legada, e olha que isso é mais comum do que pensamos.

Enfim, a nossa grande aplicação que será ativada pelo BUS via JMS, seguindo o desenho deste post se chamará “ReverseIt”, e conterá uma lógica nuclear de inverter a string que receberá como parâmetro. Não vou entrar em detalhes dos detalhes da criação do projeto na IDE, mas basicamente será um “Web Service Project” com o facet do XMLBeans Builder Library, para que ele converta nosso XSD em objetos java facilmente. A aplicação está rodando em um domínio Weblogic Server puro, em localhost:30000.

Vamos definir um schema XSD (dentro da pasta schemas) que contenha a operação de request e de response para a operação. Obviamente como temos um parâmetro string para entrada e outro para saída, ficaria algo bem trivial, basicamente o escrito abaixo:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://blog.lucastex.com/reverseit" 
        xmlns:revit="http://blog.lucastex.com/reverseit" 
        elementFormDefault="qualified">

    <element name="reverseItRequest" type="revit:ReverseItRequest"></element>
    <element name="reverseItResponse" type="revit:ReverseItResponse"></element>

    (...) definição e descrição dos tipos (...)

</schema>

Agora vamos:

  • Criar um web service como de costume
  • Configurar entrada do serviço para ReverseItRequest
  • Configurar saída do serviço para ReverItResponse
  • Escrever a lógica para inversão da palavra
     

public ReverseItResponseDocument reverseIt(ReverseItRequestDocument request) {
    
    (...) 1- Pegar input do request
    (...) 2- Inverter a string
    (...) 3- Retornar no response 

}

Legal, mas até aí temos o nosso Web Service tão padrão quanto todos que já fizemos, vamos agora para as anotações, que vão garantir que o serviço trabalhe de forma assíncrona. Bom, como ele funcionará via JMS, uma coisa que temos que fazer é criar uma fila JMS onde serão colocadas as mensagens que este serviço irá consumir, e também uma fila de resposta, para que ele coloque as mensagens de response. Não podemos esquecer também da ConnectionFactory o nosso serviço. Estes foram os nomes que eu dei:

  • Fila de Request: reversit.jms.requestQueue
  • Fila de Response: reverseit.jms.responseQueue
  • ConnectionFactory: reversit.jms.connectionFactory
Não vou entrar em detalhes da criação dos mesmos, não é este o foco da explicação.
Agora, vamos anotar nosso serviço para os resources criados.
@WLJmsTransport(serviceUri="ReverseIt", portName="ReverseItPort", connectionFactory="reverseit.jms.connectionFactory",  queue="reverseit.jms.requestQueue",  contextPath = "ReverseIt")
Nesta anotação WLJmsTransport, nós definimos o serviceURI e contextPath do serviço para que ele possa ser encontrado, também colocamos o connectionFactory e a queue de onde ele receberá as requisições, e também o nome do port que será criado no WSDL para este transporte. 
Uma coisa que pode intrigar caso alguém não esteja familiarizado com este conceito, é a doce pergunta: “Onde diabos o serviço sabe qual é a fila onde ele deverá colocar a resposta?”. Para isso, vale uma lida neste artigo sobre os padrões de resposta para mensageria assíncrona: Understanding Message ID and Correlation ID Patterns for JMS Request/Response . 
Prontinho, nosso serviço está funcionando de maneira JMS. Uma ponto muito (muito mesmo) legal e interessante, é que poderíamos expor este MESMO serviço via HTTP, apenas adicionando a anotação @WLHttpTransport com suas propriedades, e teríamos 2 ports diferentes na definição do WSDL.
Amanhã acho que consigo fazer a parte do Service BUS chamando ele, e transformando um request do terceiro (HTTP) para este nosso request (JMS). É nessa parte que tem o “pulo do gato” do produto.
Vamos deixar para testar assim que fizermos este passo.
Até,

Como diminuir o tamanho do pacote WAR de uma aplicação Grails 0

Semana passada eu havia visto este post, acabou passando em branco. Em função até do comentário do Marcos no post de Grails x Rails ter citado, acho que vale a pena deixar o link fácil pra quem precise:

Parte 1: http://thevirtualmachine.wordpress.com/2008/11/13/reducing-grails-deployment-size-by-a-lot/
Parte 2: http://thevirtualmachine.wordpress.com/2008/12/04/reducing-grails-deployment-size-part-2/

 

[]s,

Lucas

Construindo um serviço síncrono-assíncrono com Aqualogic Service BUS 0

 

Bom, um dos cenários que eu mais tenho visto ultimamente em alguns dos lugares onde tenho passado, é quando o cliente quer disponibilizar um serviço para algum terceiro, porém faz questão (e está certo), que a partir do ponto de entrada do terceiro para o barramento de serviços do cliente esta requisição seja processada de forma totalmente assíncrona. 

Com isso, o cliente (que está processando a requisição) ganha em poder de processamento, e o terceiro (que está gerando a requisição) não percebe o que se passa “under the hood” (eu realmente gosto desta expressão), sendo para ele indiferente o que acontece durante o processamento.

Basicamente, este contexto é uma implementação de um Web-Service que utiliza como meio de transporte uma Fila JMS, ao invés do protocolo HTTP que é usado de costume.

Então, vou colocar aqui um exemplo de como fazer isso usando o Aqualogic Service Bus da Oracle (já era um produto da BEA).

Serão 3 pequenas aplicações para isto.

 

  • Aplicação Legacy (é um costume horrível chamar estas aplicações de “legadas” visto que em grande parte dos processos de implementação SOA nas empresas, elas são reconcebidas, ou sofrem pelo menos, muitas alterações): É a aplicação que efetivamente possui a lógica de negócio, receberá a requisição do cliente e devolverá a resposta já processada.
  • Configuração do Service BUS: Trata-se da exposição do serviço criado na aplicação legada no service BUS, como uma operação.
  • Aplicação Tester: É a aplicação que irá consumir o serviço da aplicação legada, através da operação e endpoint disponibilizado no Service BUS.

Um desenho bem feio, mas aproximado deste cenário poderia ser este abaixo (clique para ampliar)

 

 

Diagrama do exemplo

Diagrama do exemplo (clique para ampliar)

 

Bom, como meu tempo aqui se resume a pequenos intervalos onde eu poderia escrever isto, vou separar em 3 partes, uma para cada aplicação, um post para cada. Assim que der eu já começo!

Valeu!

Web Analytics