Showing posts with label worklog. Show all posts
Showing posts with label worklog. Show all posts
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.
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)