Sunday, June 3, 2012
Worklog source code
The worklog-project can now be found on Bitbucket, https://bitbucket.org/nilsmagnus/worklog .
Wednesday, May 30, 2012
Worklog part 4: Putting my work into the cloud
After having tried cloud-foundry in combination with grails, I can only say that it is the best way I have ever experienced a deployment of a web-app.
What I have to do is:- get a cloud-foundry-beta account
- install the cloud-foundry plugin
- create a properties-file in my home-catalog/
- create a database for my app(one-liner)
- deploy app
- have a beer
Get the cloud-foundry account from cloudfoundry.com
Then install the cloud-foundry plugin by adding it to your BuildConfig.groovy.
runtime ":cloud-foundry:1.2.2"(you should probably check if a newer version is available from here)
The property-file($HOME/.grails/settings.groovy) must contain 2 properties:
grails.plugin.cloudfoundry.user=youruser grails.plugin.cloudfoundry.password=XXX
Creating a database couldn´t be simpler, to create a plain mysql database, just type
cf-create-service mysql worklog-db
Deploying the app is even simpler.
prod cf-pushAnd there you go. Congrats, the app is deployed. My app is deployed on http://webtimer.cloudfoundry.com/
Have a beer.
Worklog part3: adding some sexy ui
I bet you I know a lot of css. I´ve tried most of the tags, experimented a lot with css3 and so on. But I STILL cannot make a web-page look good. My brain is simply not wired to see what is beautiful, and even less create beautiful pages. So I frequently steal css and need all the help I can get when I´m responsible for a page design.
So therefore, twitter bootstrap is a very good choice for my pages. What I have to do is install some plugins in my app, copy some groovy-code and voilá: good-looking pages, . All I do is following the steps described on this page, except you should use the 1.2 version of fields(':fields:1.2') There you go, twitter bootstrap and nice autogenerated pages for you.
To re-generate the pages for e.g. Company, simply type
So therefore, twitter bootstrap is a very good choice for my pages. What I have to do is install some plugins in my app, copy some groovy-code and voilá: good-looking pages, . All I do is following the steps described on this page, except you should use the 1.2 version of fields(':fields:1.2') There you go, twitter bootstrap and nice autogenerated pages for you.
To re-generate the pages for e.g. Company, simply type
grails generate-all worklog.Companyand answer "a" for all on the overwrite-question.
Tuesday, May 29, 2012
Leaving a bomb in the junit-tests
If you really want to confuse your co-developers, you can leave this test hidden in your junit-tests:
@Test
public void mungle_about() throws Exception {
Field j = Integer.class.getDeclaredField("value");
j.setAccessible(true);
for (int i = -127; i <= 128; i++) j.setInt(valueOf(i), random() < 0.9 ? i : random() < 0.1 ? 42 : i + 1);
}
This will cause random tests and code to fail, since we are leaving the Integer-class in a, uhm.., not-so-correct perception of what values integers between -128 and 128 is...
Use with caution:)Source : dailywtf
Tuesday, May 22, 2012
Intellij + test coverage : duh...
As a long-time-eclipse-user, I was looking for a test-coverage tool for my erlatively newly acquired Intellij IDEA editor. At first I didn't find it, so I told myself I had to live without it, just read the testreports from my cobertura-plugin instead. confronting another intellij-user with my frustration, a nice guy called Magnus told me that IntelliJ ineed has support for test-coverage. Okay, so I'm just dumb and not finding the coverage option? Some time went on and I had accepted that intellij couldn't give me a coverage report.
Only to realzie a month later that all I had to do was to install the coverage plugin. And voila, the context-menu has the option "Run All Tests With Coverage".
Duh.
IDEA rocks btw.
Only to realzie a month later that all I had to do was to install the coverage plugin. And voila, the context-menu has the option "Run All Tests With Coverage".
Duh.
IDEA rocks btw.
Wednesday, May 16, 2012
Worklog part2: Domain objects and relations in GORM
Last time, we created the domain-class User. Meanwhile I found this name a bit ambiguous, so I renamed it to Employee. In addition to Employee, I need some other domain-objects to support my application. I need a Company, Department, Customer, Project, ProjectExpense, ProjectWorkUnit. And of course these are related in some way or another, leveraging the powers of GORM.
First off, let´s create the domain-classes using the grails interactive mode
It´s possible(and necessary) to have several relations declared in the hasMany property. For example, a project can have related both roles, expenses and work-units:
With a nice domain-model in place, I need some test-data to test my app locally. In my Bootstrap.groovy-file there is an init-method. This will be run every time the application starts, so we can add some test-data here. Grails has built-in methods to check for what environment we are in so we don´t create test-data in our production environment.
First off, let´s create the domain-classes using the grails interactive mode
// start interactive mode by typing "grails" # create-domain-class worklog.Employee # create-domain-class worklog.Company # create-domain-class worklog.Department # create-domain-class worklog.Customer # create-domain-class worklog.Project # create-domain-class worklog.ProjectExpense # create-domain-class worklog.ProjectWorkUnit # create-domain-class worklog.ProjectRoleNow, a company can have several departments. To tell GORM about this relation, I simply use the "hasMany" property in Company, along with some other sane constraints:
package worklog
class Company {
String domain
String name
Date dateCreated
static hasMany = [ department:Department]
/**
* hibernate plugin event-method
* @return
*/
def beforeInsert(){
dateCreated = new Date()
}
static constraints = {
domain(unique: true)
name(nullable: false)
}
String toString(){
domain
}
}
By default all properties are non-nullable in GORM, but I like to specify non-nullable constraints I think are important for my domain-class. The "hasMany" keyword tells GORM that Company can have 0 or more departments. The domain-property is unique for each Company, so I added the unique-constraint. Before inserting a new Company into the database, the beforeInsert() method is run by GORM, so I grab the opportunity to put a createdDate on the object.
It´s possible(and necessary) to have several relations declared in the hasMany property. For example, a project can have related both roles, expenses and work-units:
class Project{
...
static hasMany = [projectRoles: ProjectRole, projectWorkUnits:ProjectWorkUnit, projectExpenses:ProjectExpense]
...
}
Also, an employee has to know to wich department he/she belongs to, expressed by the belongsTo keyword.
...
class Employee{
static belongsTo = [department:Department]
}
...
Now, my total domain model is mapped and since I use intellij, a nice drawing of my relations are illustrated like this:With a nice domain-model in place, I need some test-data to test my app locally. In my Bootstrap.groovy-file there is an init-method. This will be run every time the application starts, so we can add some test-data here. Grails has built-in methods to check for what environment we are in so we don´t create test-data in our production environment.
class BootStrap {
def init = { servletContext ->
switch (Environment.current) {
case Environment.DEVELOPMENT:
Company webstep = new Company(name: "webster", domain: "webstep.no").save()
Department oslo = new Department(company: webstep, name: "Konnsulting", city: "Oshlo").save()
Employee nils = new Employee(department: oslo, email: "nilsmagnus@gmail.com", securityRole: SecurityRole.NORMAL).save()
Customer icu = new Customer(name: "icu").save()
Project icuRefactoring = new Project(department: oslo, customer: icu, name: "refactoring legacy code").save()
ProjectRole developer = new ProjectRole(employee: nils, project: icuRefactoring, hourRate: 1200.0, description: "Develop some cool shait").save()
ProjectExpense calculatorPurchase = new ProjectExpense(description: "new calculator", project: icuRefactoring, projectRole: developer, amount: 1300.0 ).save()
break
}
}
}
This fills in some data for testing purposes, now we just need to see the data in our app. To get started with ui, I think it´s nice to generate html and controllers with grails using the built in "generate-all" command. For each domain-class I enter the command
# generate-all worklog.Employee .... # run-appAnd its time for inspection :) To recap: GORM takes care of database-mapping and intellij shows you the relations in your app. Easy as that. Next time: some testing. Later on I will be doing the gorm critierias to create nice reports.
Thursday, May 10, 2012
Worklog part1: Up and running with authentication
Intention of this session: create a User object and use google to log in.
First I need to create my grails app from the command line(assuming I have installed it first)
Then enter interactive-mode by typing
To create a domain-class for we simply type
Now, we need to add some properties to the user, a unique field called email of type String.
String email
So to check that we have a running application, we create some views and run our app locally to see what we have:
Now we get down to business. I need authentication! Luckily there are some grails-plugins for that, lets see... I kind of like the sound of the oauth-plugin, so I think I will try that. Installation: always install it by adding it to the BuildConfig-file(as opposed to installing it command-line-style). That way it´s easy to keep track of what you have installed, and upgrade will be less painful. At the time, the version is 1.0, so I add this to my BuildConfig in the plugin-section (current version is 2.0.1, check if it has been updated):
Now, replace the key and with some sane value and same for the secret (my settings wont work well for you, and will change in a bit). Obtain this from google (go to the apis console link). Of course, now we need to create the success and failure uris...
This concludes the goal of this session, next time I will work more on domain-objects and setting up some test-data (users) for the app.
First I need to create my grails app from the command line(assuming I have installed it first)
# grails create-app webtimer
Then enter interactive-mode by typing
# grails
To create a domain-class for we simply type
# create-domain-class worklog.User
Now, we need to add some properties to the user, a unique field called email of type String.
String email
So to check that we have a running application, we create some views and run our app locally to see what we have:
# generate-all worklog.User # run-app(notice that you get autocompletion by pressing "tab" in interactive-mode)
The app should now be running on localhost:8080/worklog :
Voila, the app is running.Now we get down to business. I need authentication! Luckily there are some grails-plugins for that, lets see... I kind of like the sound of the oauth-plugin, so I think I will try that. Installation: always install it by adding it to the BuildConfig-file(as opposed to installing it command-line-style). That way it´s easy to keep track of what you have installed, and upgrade will be less painful. At the time, the version is 1.0, so I add this to my BuildConfig in the plugin-section (current version is 2.0.1, check if it has been updated):
compile ':oauth:2.0.1'
Thats it? Nope. We need to configure it to authenticate with google. In my Config.groovy, I need to add
oauth {
providers {
google {
api = GoogleApi
key = '1057869129521.apps.googleusercontent.com'
secret = 'zaOsvnGrxyZ0kRciJJew0xbb'
successUri = '/authenticate/success'
failureUri = '/authenticate/failure'
scope = 'https://www.googleapis.com/auth/userinfo.email'
callback = "${grails.serverURL}/oauth/callback"
}
}
}
Now, replace the key and with some sane value and same for the secret (my settings wont work well for you, and will change in a bit). Obtain this from google (go to the apis console link). Of course, now we need to create the success and failure uris...
# create-controller worklog.auth.AuthenticateWow. Ok, lets see if we can poke around with this. In the index.gsp, we add some code:
<oauth:connect provider="google">Log in with google</oauth:connect>And in our Authenticate-controller, we add a service and a method for the "authenticate/success"
OauthService oauthService
def success() {
Token googleAccessToken = session[oauthService.findSessionKeyForAccessToken('google')]
def userInfo = oauthService.getGoogleResource(googleAccessToken, 'https://www.googleapis.com/oauth2/v1/userinfo')
def mail = JSON.parse(userInfo.body)
render "Authenticated as $mail"
}
Test and check, heres my result;
Subscribe to:
Posts (Atom)




