Annotations « Intelligrape Groovy & Grails Blogs

Posts Tagged ‘ Annotations ’

@Canonical annotation

Posted by on September 27th, 2012

@Canonical: It’s very useful annotation. It provides the combination of features of @ToString (default implementation of toString() method based upon the fields in the class), @EqualsAndHashCode(default implementation of equals() and hashCode() method of the class based upon the fields in the class) and @TupleConstructor (provides the classical constructor with default properties).

import groovy.transform.Canonical

@Canonical
class Person {
String name
String address
String city

}

Person person = new Person(name:"Mohit Garg",address:"Address",city: "city")
Person person1 = new Person("Mohit Garg","Address","city")

println("Check two objects are equal:::"+(person.equals(person1)))  // Both objects will be equal because of same hashCode. (Output:true)

println("person object:::"+person) //Output:Person(Mohit Garg, Address, city)

Hope this will help you :)

Thanks & Regards,
Mohit Garg
mohit@intelligrape.com
@gargmohit143

Posted in Groovy

Attributes of Spring Cache

Posted by on September 25th, 2012

In my previous blog, i have mentioned how to integrate spring cache plugin in grails. In this blog we will see how we can use different attributes of cache.

Different attributes of cache :-

  1. maxElementsInMemory- How many elements you can store in cache
  2. overflowToDisk-The attribute overflowToDisk is true, meaning that whenever the maximum number of in-memory objects is reached, objects are swapped to disk
  3. diskPersistent – if diskPersistent is false, it means when application server is restarted, in-memory cache is lost.
  4. ttl(time to live seconds)- It denotes for how many seconds element will remain in cache?
  5. memoryStoreEvictionPolicy – It is used to evict element from in-memory when the maximum number of in-memory objects is reached . Different type of eviction policy:
  6. a) LRU (Least Recently Used): Oldest element will be evicted.
    b) LFU (Least Frequently Used): Element with least hits will be evicted.

In grails, you can implement different cache attributes like this way.

studentCache(EhCacheFactoryBean) { bean ->
cacheManager = ref("springcacheCacheManager")
cacheName = "studentCache"
eternal = false
diskPersistent = false
memoryStoreEvictionPolicy = "LRU"
ttl = 3000
}

Hope this code will help you :)

To know more about Cache, you can take the reference by using below link.
http://grails.org/plugin/springcache
http://www.intelligrape.com/blog/2012/09/25/how-to-integrate-spring-cache-plugin-with-grails/

Thanks & Regards,
Mohit Garg
mohit@intelligrape.com
@gargmohit143

Posted in Grails

How to integrate Spring cache plugin with Grails

Posted by on September 25th, 2012

In one of my recent project, i want to cache  method output. For implementing method level cache, i have used spring cache. For implement Spring cache, we can use grails cache plugin.

It’s very easy to integrate cache plugin with grails.

1. Add following plugin dependency in BuildConfig.groovy.

compile ":springcache:1.3.1"

2.  We need to define the caches in resource.groovy. Use below mention code to create cache in resources.groovy.


studentCache(EhCacheFactoryBean) { bean ->
cacheManager = ref("springcacheCacheManager")
cacheName = "studentCache"
memoryStoreEvictionPolicy = "LRU"
}

EhCacheFactoryBean – Pre define class of the spring
studentCache – Cache name

3. Add following codes in Config.groovy file to enable cache.

springcache {
    defaults {
        eternal = false
        diskPersistent = false
    }
    caches {
        studentCache {
            memoryStoreEvictionPolicy = "LRU"
           ttl=1000
        }
    }
}

We need to mention the cache name that we want to enable. We can enable multiple cache.

4. Add @Cacheable annotation above method that you want to cache.

@Cacheable(cache="studentCache")
    Student showStudent(long id){
        return Student.get(id)
    }

@Cacheable – We need to pass cache name
But one thing we need to ensure, the class in which we are implementing the cache, it should be managed by spring or grails.
Run server, hit the url, you can see our method output is cached.
Hope so this code will work for you :)

To know more about Cache, you can take the reference by using below link.
http://grails.org/plugin/springcache

Thanks & Regards,
Mohit Garg
mohit@intelligrape.com
@gargmohit143

Posted in Grails

Restricting Access To Plugin’s Classes With Spring Security

Posted by on May 3rd, 2012

Many of Grails plugin like searchable  and console can prove to be really dangerous if access to their URLs is not blocked. After adding searchable plugin to my project, I realized that access to its controllers was not defined and was open for all. Now this was a major security concern. There are many ways of restricting access like doing it manually in filters. But since I am using spring security plugin, there was a better way out. It allows to create mapping (static rules) as configuration for different user roles.

There are different ways of securing url in spring security plugin. And since I am using annotations, I’ll be defining static rule for annotations only.


grails.plugins.springsecurity.controllerAnnotations.staticRules = [

'/console/**': ['ROLE_ADMIN'],

'/searchable/**': ['ROLE_ADMIN']

]

By doing this I blocked access for all but ones with the role “ROLE_ADMIN”  for console and searchable controllers.

_________________________________
Hitesh Bhatia
Mail,LinkedIn,Facebook,Twitter
_________________________________
Posted in Grails

Annotation for checking required session fields

Posted by on September 21st, 2011

Recently I worked on a project where I used spring security plugin. Its a very wonderful plugin for making your application secured from unauthorized users. It gives you a simple annotation @Secured to add security to your action and controller. Thats the first time I got to know the real use case of annotation. So I started reading about annotation and few days later I found the use case to implement my own annotation.

All the projects I have worked on had login functionality where we put the userId and projectId into the session. Then in my code I use to get the user from session.userId. Something like

def books = {
   User user = User.get(session.userId)
   Project project = Project.get(session.projectId)
   ......
   .....
}  

The above code fails when user directly hits this action because there is no check to verify the user is not null. The simple answer for this problem is either use beforeInterceptor or filters. So we started checking the session.userId in filters. But again there are cases where you dont want to check this session value or you can say there are public urls as well. Now we have to put few if else statements in filter.

Here I got my use case to implement an annotation for controllers and actions which checks for the required fields in the session before getting into the action. So I created an annotation in src/groovy folder

import java.lang.annotation.ElementType
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
import java.lang.annotation.Target

@Target([ElementType.FIELD, ElementType.TYPE]) // Annotation is for actions as well as controller so target is field and for class
@Retention(RetentionPolicy.RUNTIME) // We need it at run time to identify the annotated controller and action
@interface RequiredSession {
    String[] exclude() default [] // To exclude some of the actions of controller

    String[] fields() default ["userId","projectId"] // The default value is set to userId and projectId that can be overridden while using the   annotation on controller or action.

    String onFailController() default "home" // Default controller when the field not in session is set to index page

    String onFailAction() default "index" // Default action when the field not in session is set to index page
}

Now I created a ApplicationFilters and before redirected the request to any action I check for the condition of session fields if the requested action or controller is annotated. The code in the filter is something like

class ApplicationFilters {
    def filters = {
        validateSession(controller: '*', action: '*') {
            before = {
                if (controllerName) {
                    
//Get the instance of controller class from string value i.e; controllerName
                    def controllerClass = grailsApplication.controllerClasses.find {it.logicalPropertyName == controllerName}
                    
//Read the RequiredSession annotation from controller class  
                    def annotation = controllerClass.clazz.getAnnotation(RequiredSession)
                   
//Get the current action from actionName otherwise read default action of controller    
                    String currentAction = actionName ?: controllerClass.defaultActionName
                   
//Look for the annotation on action if controller is not annotated or the action name is excluded
                    if (!annotation || currentAction in annotation.exclude()) {

//Get the action field from string value i.e; currentAction
                        def action = applicationContext.getBean(controllerClass.fullName).class.declaredFields.find { field -> field.name == currentAction }
//If action is found get the annotation else set it to null 
                        annotation = action ? action.getAnnotation(RequiredSession) : null
                    }
                    
//Check for the field in session whether the are null or not if any of the field is null loginFailed is true  
                    boolean loginFailed = annotation ? (annotation.fields().any {session[it] == null}) : false

                    if (loginFailed) {

// If login is failed user redirected to on fail action and controller
                        redirect(action: annotation.onFailAction() , controller: annotation.onFailController())
                        return false;
                    }
                }
            }

        }
    }
}


And its all done. Now we just annotate our controller and actions accordingly.

@RequiredSession(exclude = ["registration", "joinProject"])
class UserController {
      def edit ={}
      def update = {}
      def list ={}
      def save ={}

      def registration ={}
      def joinProject = {}
}

In above example registration and joinProject action will bypass the session fields check.

@RequiredSession
class ItemController {
        def index={}
        def buy ={}
        def save ={}
} 

All the action of above examples can be accessed only when user is logged in.

class HomeController {
      def index ={}
      def aboutUs={}
      @RequiredSession
      def dashboard = {}
}

Actions other than dashboard are public actions which can be accessed without login.

class UserController {
  @RequiredSession(fields = ["loggedInUserId"])
   def updatePassword = {
    
   }
}

For updating password user dont need to have some project into session so we specified the fields to be checked in session.

Hope it helps
Uday Pratap Singh
uday@intelligrape.com
https://twitter.com/meudaypratap
http://in.linkedin.com/in/meudaypratap

Grails Transactions using @Transactional annotations and Propagation.REQUIRES_NEW

Posted by on July 30th, 2010

Hi All,

Here is how you can implement a new transaction in an already executing transaction in Grails which uses nothing but Spring framework’s Transaction mechanism as an underlying implementation. Spring provides @Transactional annotations to provide declarative transactions. We can use the same in our Grails project to achieve the transactional behavior.

Here is the scenario: You have two domain classes named SecuredAccount and AccountCreationAttempt. You try to transactionally save the SecuredAccount object which in turn creates a AccountCreationAttempt object which writes to the database stating: “There is an attempt to create a new SecuredAccount at this time: <current date and time>”. Point to note here is that even if the creation of the new SecuredAccount object fails, the record must still be written to the database so that the Administrator can validate whether the attempt at the specific time was by a legitimate user or an attacker.

Here is the code:

import org.springframework.transaction.annotation.*
Class MyService {
 
static transactional = false
def anotherService
 
@Transactional
def createSecuredAccount() {
def securedAccount = new SecuredAccount(userId:"John")
securedAccount.save(flush:true)
anotherService.createAccountCreationAttempt()
throw new RuntimeException("Error thrown in createSecuredAccount()")
}
}
import org.springframework.transaction.annotation.*
class AnotherService {
 
static transactional = false
 
@Transactional(propagation = Propagation.REQUIRES_NEW)
def createAccountCreationAttempt() {
def accountCreationAttempt = new AccountCreationAttempt(logRemarks: "There is an attempt to create a new SecuredAccount at this time: {new Date()}")
accountCreationAttempt.save(flush:true)
}
}

Now in this scenario, AccountCreationAttempt object always gets persisted whether or not the transaction for creating SecuredAccount object fails.

Here are few gotchas regarding the above transactions:

1.) First of all, for Propagation.REQUIRES_NEW to work as intended, it has to be inside a new object i.e. a new service in our example. If we had put the createAccountCreationAttempt() method in the MyService there would be no new transaction spawned and even no log entry would be made. This is Spring’s proxy object implementation of transactions and you can read more about it here:

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative-annotations.

Please pay special attention to the “NOTE” sub-section.This is what it states:

“In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.”

2.) Secondly, all the @Transactional methods should have a public visibility i.e. createSecuredAccount() and createAccountCreationAttempt() methods should be public methods, and not private or protected. This again is Spring’s @Transactional annotations implementation and you can read about it at the same link as provided above. Note the right side-bar titled “Method visibility and @Transactional“.

Well, once you keep note of these gotchas I guess you are all set to make good use of @Transactional annotations and its full power.

Cheers !!!

- Abhishek Tejpaul
abhishek@intelligrape.com
[IntelliGrape Software Pvt. Ltd.]

Posted in Database, Grails, Groovy