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.
delahuntyware
Software engineer by day, web ideas maniac by night. This Blog is about my experience as a web entrepreneur. The tools i use (grails, groovy, java, css, ec2), the problems i solve, the books i read. Basically an over all brain dump... enjoy :)
Monday, August 29, 2011
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)
Next create a filter that uses Spring security plugin to fetch the current logged in user:
That is it
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
Install apache
sudo yum install httpd httpd-devel
add /etc/httpd/conf.d/proxy_ajp.conf
With this in it:
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
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:
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:
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.
Hope this helps someone.
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.
Thursday, October 14, 2010
Stored procedures on Amazon RDS
Been a long time since i blogged but need to document this pain in the arse.
So for a new project i need to create a mysql function (same for stored proc) on amazon RDS.
When i tried to install it i got this error:
ERROR 1419 (HY000) at line 3: You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
So to get them to install you need to set that database parameter to ON. However to do that is not so simple.
Lucky for you people i have found out how to do it and here are the steps:
1) Install the RDS CLI tools. I installed these on my EC2 instance.
Download from here:
http://developer.amazonwebservices.com/connect/entry.jspa?categoryID=294&externalID=2928
They are java based and so you need have Java running. Plus they need your amazon key and secret key. Once you have them installed following the readme do the following:
Important!! make sure you set the AWS region you are working in.
Eg export EC2_REGION=ap-southeast-1
2) create a new parameter group
rds-create-db-parameter-group peters-params -f mysql5.1 -d "peters params"
3) modify the log_bin_trust_function_creators to be set to ON
rds-modify-db-parameter-group peters-params --parameters="name=log_bin_trust_function_creators, value=on, method=immediate"
4) change your running db instance to use the new param group
rds-modify-db-instance petersdbinstance --db-parameter-group-name=peters-params
5) restart the instance
rds-reboot-db-instance petersdbinstance
That will allow you to create a function or stored procedure:
Some point about the function / stored proc:
You need to specify the DETERMINISTIC stuff and you need to add a DEFINER=CURRENT_USER
DELIMITER $$
DROP FUNCTION IF EXISTS `sayhello`$$
CREATE DEFINER=CURRENT_USER FUNCTION `sayhello`(param1 VARCHAR(120))
RETURNS VARCHAR(120)
NOT DETERMINISTIC
READS SQL DATA
BEGIN
RETURN CONCAT('Hello, ',s,'!');
END$$
DELIMITER ;
This works for me hope it helps
So for a new project i need to create a mysql function (same for stored proc) on amazon RDS.
When i tried to install it i got this error:
ERROR 1419 (HY000) at line 3: You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
So to get them to install you need to set that database parameter to ON. However to do that is not so simple.
Lucky for you people i have found out how to do it and here are the steps:
1) Install the RDS CLI tools. I installed these on my EC2 instance.
Download from here:
http://developer.amazonwebservices.com/connect/entry.jspa?categoryID=294&externalID=2928
They are java based and so you need have Java running. Plus they need your amazon key and secret key. Once you have them installed following the readme do the following:
Important!! make sure you set the AWS region you are working in.
Eg export EC2_REGION=ap-southeast-1
2) create a new parameter group
rds-create-db-parameter-group peters-params -f mysql5.1 -d "peters params"
3) modify the log_bin_trust_function_creators to be set to ON
rds-modify-db-parameter-group peters-params --parameters="name=log_bin_trust_function_creators, value=on, method=immediate"
4) change your running db instance to use the new param group
rds-modify-db-instance petersdbinstance --db-parameter-group-name=peters-params
5) restart the instance
rds-reboot-db-instance petersdbinstance
That will allow you to create a function or stored procedure:
Some point about the function / stored proc:
You need to specify the DETERMINISTIC stuff and you need to add a DEFINER=CURRENT_USER
DELIMITER $$
DROP FUNCTION IF EXISTS `sayhello`$$
CREATE DEFINER=CURRENT_USER FUNCTION `sayhello`(param1 VARCHAR(120))
RETURNS VARCHAR(120)
NOT DETERMINISTIC
READS SQL DATA
BEGIN
RETURN CONCAT('Hello, ',s,'!');
END$$
DELIMITER ;
This works for me hope it helps
Labels:
amazon RDS stored procedure
Monday, November 2, 2009
how to setup clover with multi-module maven project and build with bamboo
Ok so i figured how to setup clover with maven on a mulit-module project with putting the config in a maven profile:
Simply drop that into your profiles section in your pom. You will need to change the paths of where you have put your clover licence and where you want the snapshots to be stored. Then when you want to run it use this command.
Bamboo
Setup bamboo as normal but make sure you don't let bamboo clear out your build directory each time or clover won't work. So untick the option to clean out the build directory each time.
<profile>
<id>clover</id>
<build>
<plugins>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-clover2-plugin</artifactId>
<configuration>
<targetPercentage>${clover.coverage.percent}</targetPercentage>
<snapshot>/development/build-server/clover/${groupId}-${artifactId}/clover.snapshot</snapshot>
<generateHtml>true</generateHtml>
<generateXml>true</generateXml>
<baseDir>${project.basedir}</baseDir>
<licenseLocation>/development/build-server/clover/clover.license</licenseLocation>
</configuration>
<executions>
<execution>
<id>clover</id>
<goals>
<goal>setup</goal>
<goal>snapshot</goal>
</goals>
</execution>
<execution>
<phase>verify</phase>
<goals>
<goal>aggregate</goal>
<goal>clover</goal>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
Simply drop that into your profiles section in your pom. You will need to change the paths of where you have put your clover licence and where you want the snapshots to be stored. Then when you want to run it use this command.
mvn -P clover install
Bamboo
Setup bamboo as normal but make sure you don't let bamboo clear out your build directory each time or clover won't work. So untick the option to clean out the build directory each time.
Subscribe to:
Posts (Atom)