Sunday, February 3, 2013

Grails Error: No thread-bound request found


No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

Sometime you get this error with spring security. Most common when upgrading grails because all the dependencies have to be re downloaded.

To fix just clean and compile your grails project. Then run run-app twice. Seem to fix the issue.

403 AWS elastics bean stalk

This is for anyone having a problem with seeing 403 errors on AWS.


The problem is when your minimum number of instances does not match the availability Zone number. So if one of your instances goes down in the AZ the load balancer seems to still try to send connections to it and that strangely results in a 403.

So it is easily fixed. Just make sure your min instance count number matches the Any values eg


Min instance count = 1
AZ = Any1


Min instance count = 2
AZ = Any2


Min instance count = 3
AZ = Any3

Hope this helps someone. It was a pain for me to track this down.

P



Monday, August 29, 2011

My latest Web service is LIVE

It's been a while since i last posted. But i have been busy working on this new service.

http://www.hugglehub.com

The service is all about making it easy to share you photos with your parents.

Check it out let me know what you think.

Monday, May 16, 2011

User tracking logging in Grails

Hi peeps

Thought i would just do a quick post about how to create a custom logging filter for logging which pages a user went to.

First setup log4j config to add a new apppender nd logger called utlog (usage tracking)

 def utLog = "${System.properties.getProperty('catalina.base')}${File.separator}logs${File.separator}utlog.log"  
println utLog
log4j = {
appenders {
rollingFile name: 'utlog', file: utLog, layout: pattern(conversionPattern: '%d{dd-MM-yyyy HH:mm:ss,SSS}|%p|%c{1}|%X{userId}|%X{sessionId}|%m%n'), maxFileSize: '10MB', threshold: org.apache.log4j.Level.DEBUG
console name: 'stdout', layout:pattern(conversionPattern: '%d{dd-MM-yyyy HH:mm:ss,SSS}|%p|%c{1}|%X{userId}|%X{sessionId}|%m%n'), threshold: org.apache.log4j.Level.DEBUG
}
error 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails.web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework',
'org.hibernate',
'net.sf.ehcache.hibernate'
warn 'org.mortbay.log'
info utlog: ['ut'],additivity:true
}



Next create a filter that uses Spring security plugin to fetch the current logged in user:

 class UsageTrackingFilters {  
def springSecurityService
private static final Log usagetrackingLog = LogFactory.getLog('ut')
def filters = {
all(controller: '*', action: '*') {
before = {
String sessionId = RequestContextHolder.getRequestAttributes()?.getSessionId()
if (sessionId) {
MDC.put('sessionId', sessionId)
}
if (springSecurityService.isLoggedIn()) {
def userId = springSecurityService.getPrincipal().id
MDC.put('userId', userId + "")
}else{
MDC.put('userId', "0")
}
usagetrackingLog.info(request.getRequestURI())
}
after = {
}
afterView = {
MDC.remove('sessionId')
MDC.remove('userId')
}
}
}
}


That is it

Saturday, February 26, 2011

Setup Amazon linux for Grails

Install mysql

yum install mysql mysql-server mysql-libs
service mysqld start
chkconfig --levels 235 mysqld on
mysql_secure_installation



Install apache

sudo yum install httpd httpd-devel

add /etc/httpd/conf.d/proxy_ajp.conf

With this in it:

<Ifmodule mod_proxy_ajp.c>
ProxyRequests On
ProxyVia On

<Location />
Order allow,deny
Allow from all
ProxyPass ajp://localhost:8009/
ProxyPassReverse ajp://localhost:8009/
</Location>

</Ifmodule>

Wednesday, October 20, 2010

Grails GORM trick: Use read() rather than get() on updates

Hi

So i discovered that it might be a good idea use read() on your update method.

So use

def person = Person.read(params.id)

instead of

def person = Person.get(params.id)

The consequence of this is that hibernate dirty checking is turned off. So to save your domain object you MUST call save(). So if you cancel the update for any reason without calling save() you do not have to to worry about grails persisting things automatically due to dirty checking :)

Hope this helps

Sunday, October 17, 2010

GORM gotcha: Many to Many mapping causing new Domain to be saved

Hi All

I came across a new Grails GORM subtle gotcha this week.

I was creating a new Domain object and it was still getting persisted to the database even though i was not calling save().

This is not normal behavior for NEW objects. As you may or may not be aware this is the behavior when updating objects though. So i was quite surprised by this and did some trials in trying to fix the problem.

First calling discard() on my NEW object was the first try. But that was a guess and i knew really it would not work. Because that object not yet associated with the session. And it didn't. So i finally found the problem.

This was all to do the the many to many relationship that was setup on the domain object.

So for example i have somethings like this:

class Location {

static hasMany = [posters:Poster]

String name

}

class Poster {

static belongsTo = [Location]

static hasMany = [locations:Location]

String name

}




So in my controller i allow a user to select multiple locations. These locations all get added to the new Poster in this line of code:

Poster poster = new Poster(params)




So if i then have some business logic that decides that i do not want to create this new Poster i just need to not call save right. Turns out that is wrong.

Because of the many to many relationship between Location and Poster. Poster has been assoiated with the locations. So the locations are now dirty and will get persisted at the end of the transaction. This will cascade to my new Poster and save it.

So to fix this you need to discard the Location objects so they do not save your Poster object.

Poster poster = new Poster(params)

if(businessLogicValidate() == false){

poster.locations.each{Location l ->
l.discard();
}

}else{

poster.save()

}





Hope this helps someone.