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-push
And 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
grails generate-all worklog.Company
and 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.

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
// 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.ProjectRole
Now, 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-app
And 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)
# 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.Authenticate
Wow. 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;


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.

Creating an advanced webapp: "work-log" with grails

I have played with the idea of creating my own time-tracker app, and after some prototyping I think I have some useful ideas. So I will hopefully have a series of blog posts where I describe the different 

First of all: my #1 tool is grails. I´m a java-dude, but after playing around with grails for a while I know that java cannot compete with the productivity of grails. 

Second: for authentication I need to use google(it would be nice to integrate with their marketplace for google-apps if this goes anywhere). The users have to be divided into 1) uber-users(me, or the application-maintainer), 2) super-users for a company(CEO) 3) department-managers 4) normal users

Third: I´m no design guru, so I need some good css styling for free. I´m thinking maybe twitter-bootstrap can help me out, but i´m not sure yet. 

Fourth: my domain-model will fit the needs of a multi-department organisations with local managers and company-wide managers. 

Fifth: I need to export data as csv and pdf to create some invoices. Maybe with customized logos. Don´t know how I will do this yet, but I have some experience with itext and "flying saucer".

I will post all my progress on github, and have (hopefully) frequent deployments to cloudfoundry. 

more to come....