Showing posts with label Grails. Show all posts
Showing posts with label Grails. Show all posts

Monday, 10 December 2012

Hacking on grails twitter bootstrap

STEP 1 : create a grails-app
prayag@Prayag:~/workspace_grails$ grails create-app eccount --stacktrace

STEP 2 : add twitter-bootstrap resources plugin to grails-app/conf/BuildConfig.groovy

plugins {
// install twitter-bootstrap resources plugin
// https://github.com/iPrayag/twitter-bootstrap-scaffolding
runtime ":twitter-bootstrap:2.1.1"

// install Fields plugin  successor to the bean-fields plugin
 //that attempts to provide a configurable way to render forms
runtime ":fields:1.3"
}

STEP 3 : compile app
prayag@Prayag:~/workspace_grails/eccount$ grails compile
Downloading: grails-twitter-bootstrap-2.1.1.zip
[...]

STEP 4 : clone twitter-bootstrap-scaffolding from github

STEP 5 : copy following files from twitter-bootstrap-scaffolding to newly created grails-app

twitter-bootstrap-scaffolding/src/templates/scaffolding/*
twitter-bootstrap-scaffolding/web-app/css/scaffolding.css
twitter-bootstrap-scaffolding/grails-app/conf/ScaffoldingResources.groovy
twitter-bootstrap-scaffolding/grails-app/taglib/**/*
twitter-bootstrap-scaffolding/grails-app/views/index.gsp
twitter-bootstrap-scaffolding/grails-app/views/layouts/bootstrap.gsp
twitter-bootstrap-scaffolding/grails-app/views/_fields/default/_field.gsp

STEP 6 : Generate scaffold
prayag@Prayag:~/workspace_grails/eccount$ grails generate-all eccount.Stall

STEP 7 : run-app 
prayag@Prayag:~/workspace_grails/eccount$ grails run-app


References
1 - twitter-bootstrap-scaffolding by robfletcher, https://github.com/iPrayag/twitter-bootstrap-scaffolding
2 - Try Person List, http://grails-twitter-bootstrap.cloudfoundry.com/person/list

Thursday, 8 November 2012

Hacking on grails and mongodb

Part A : Connecting grails to mongodb

STEP 1 install mongodb
Install mongodb as described in STEP 5 here.

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
$ echo 'deb http://downloads-distro.mongodb.org/repo/debian-sysvinit dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list

$ sudo apt-get update
$ sudo apt-get install mongodb-10gen

Or, there is mongohq.com with upto 512M for sandbox mongodb hosting.

STEP 2 : add mongodb plugin dependency
[METHOD 1]
Add mongodb dependency to grails-app/conf/BuildConfig.groovy

dependencies {
        // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.

        // runtime 'mysql:mysql-connector-java:5.1.20'

        // httpbuilder
        compile('org.codehaus.groovy.modules.http-builder:http-builder:0.5.0') {
                     excludes "commons-logging", "xml-apis", "groovy"
        }
       //mongodb dependency with no need to grails install-plugin mongodb
       compile ":mongodb:1.0.0.GA"
    }
NOTE: 
In older versions of Grails,   
application.properties was the only place where plugin dependencies could be specified. 
In Grails 1.2.X (or thereabouts) 
grails-app/conf/BuildConfig.groovy was introduced as the preferred place to specify plugin dependencies, but application.properties is still supported.

[METHOD 2] 
prayag@prayag:~/workspace_grails/eccount$ grails install-plugin mongodb
 Downloading: spring-data-mongodb-parent-1.0.0.RELEASE.pom.sha1
 Downloading: mongo-java-driver-2.7.1.pom.sha1
 Downloading: grails-datastore-gorm-1.0.7.RELEASE.pom.sha1
 Downloading: grails-datastore-gorm-plugin-support-1.0.7.RELEASE.pom.sha1
 [..]
 Plugin installed.


STEP 3 : remove hibernate plugin dependency
prayag@prayag:~/workspace_grails/eccount$ grails uninstall-plugin hibernate
OR
just remove or comment this line of code runtime ":hibernate:$grailsVersion" in  /grails-app/conf/BuildConfig.groovy
    plugins {
        //runtime ":hibernate:$grailsVersion"
        runtime ":jquery:1.8.0"
        runtime ":resources:1.1.6"

        // Uncomment these (or add new ones) to enable additional resources capabilities

        //runtime ":zipped-resources:1.0"
        //runtime ":cached-resources:1.0"
        //runtime ":yui-minify-resources:0.1.4"

        build ":tomcat:$grailsVersion"


        runtime ":database-migration:1.1"


        compile ':cache:1.0.0'

    }

STEP 4 : Create domain-class
Create domain-class and add some properties with mapping static mapWith="mongo"
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ sudo vi grails-app/domain/whotweetsnepal/Post.groovy

package whotweetsnepal


class Post {

    String username;
    String status;
    Date created = new Date();
    static mapWith="mongo"
    static constraints = {
        created(display:false)
    }
}


STEP 5 : Compile the app
prayag@prayag:~/workspace_grails/whotweetsnepal$ grails compile

STEP 6 : run the app
prayag@prayag:~/workspace_grails/whotweetsnepal$ grails run-app

STEP 7 : check mongodb
prayag@prayag:~$ mongo
MongoDB shell version: 2.2.1
connecting to: test

> show dbs;

WhoTweetsNepal  0.0625GB
local   (empty)
> use WhoTweetsNepal;
switched to db WhoTweetsNepal

If there is a error connecting to mongo, with exception :
$ mongo
MongoDB shell version: 2.2.3
connecting to: test
Sat Aug 31 05:42:52 Error: couldn't connect to server 127.0.0.1:27017 src/mongo/shell/mongo.js:91
exception: connect failed

follow the following commands
$ sudo rm /var/lib/mongodb/mongod.lock
$ sudo -u mongodb mongod -f /etc/mongodb.conf --repair

And then start service mongodb (with sudo privilege) and verify the port with
$ lsof -iTCP
And now try connecting,
$ mongo

Some mongo commands for productivity,

> cls or 
> Ctrl+l   -> clear console

If it's mongohq.com as a mongodb hosting, fire the following command to connect server
$ mongo paulo.mongohq.com:10012/WhoTweetsNepal -u prayagupd -p
MongoDB shell version: 2.2.3
Enter password: 
connecting to: paulo.mongohq.com:10012/WhoTweetsNepal
>

References
http://etcpe9.wordpress.com/2012/01/28/beginning-grails-2-0-with-mongodb/
https://github.com/mpriatel/mongodb-grails/wiki
http://mattwallace.me/mapping-current-grails-domain-classes-to-use
http://blog.mongodb.org/post/18510469058/grails-in-the-land-of-mongodb





Part B Using spring-security-core and spring-security-twitter

STEP 1 Install Spring-Security plugin, a fast and convenient solution for authorizing user access
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails install-plugin spring-security-core
Downloading: spring-security-core-1.2.7.3.pom
| Resolving plugin JAR dependencies

*******************************************************

* You've installed the Spring Security Core plugin.   *
*                                                     *
* Next run the "s2-quickstart" script to initialize   *
* Spring Security and create your domain classes.     *
*                                                     *
*******************************************************
| Plugin installed.



Next run the “s2-quickstart” script to initialize Spring Security and create domain classes.
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails s2-quickstart
| Compiling 153 source files
Usage: grails s2-quickstart <domain-class-package> <user-class-name> <role-class-name> [requestmap-class-name]
Creates a user and role class (and optionally a requestmap class) in the specified package
Example: grails s2-quickstart com.yourapp User Role
Example: grails s2-quickstart com.yourapp Person Authority Requestmap

The above script asks to run it with the specification of the classes names that should be generated.

The final s2-quickstart script will be as follows:
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails s2-quickstart com.zazzercode.whotweetsnepal User Role
| 
*******************************************************
* Created domain classes, controllers, and GSPs. Your *
* grails-app/conf/Config.groovy has been updated with *
* the class names of the configured domain classes;   *
* please verify that the values are correct.          *
*******************************************************


[1.1] Check the views/
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ ls -l grails-app/views/login/
total 8
-rw-rw-r-- 1 prayag prayag 2721 Nov  8 14:40 auth.gsp
-rw-rw-r-- 1 prayag prayag  237 Nov  8 14:40 denied.gsp

The /login/auth.gsp is as follows :
<body>
<div id='login'>
        <div class='inner'>
                <div class='fheader'><g:message code="springSecurity.login.header"/></div>

                <g:if test='${flash.message}'>
                        <div class='login_message'>${flash.message}</div>
                </g:if>

                <form action='${postUrl}' method='POST' id='loginForm' class='cssform' autocomplete='off'>
                        <p>
                                <label for='username'><g:message code="springSecurity.login.username.label"/>:</label>
                                <input type='text' class='text_' name='j_username' id='username'/>
                        </p>

                        <p>
                                <label for='password'><g:message code="springSecurity.login.password.label"/>:</label>
                                <input type='password' class='text_' name='j_password' id='password'/>
                        </p>

                        <p id="remember_me_holder">
                                <input type='checkbox' class='chk' name='${rememberMeParameter}' id='remember_me' <g:if test='${hasCookie}'>checked='checked'</g:if>/>
                                <label for='remember_me'><g:message code="springSecurity.login.remember.me.label"/></label>
                        </p>

                        <p>
                                <input type='submit' id="submit" value='${message(code: "springSecurity.login.button")}'/>
</p>
                </form>
        </div>
</div>
<script type='text/javascript'>
        <!--
        (function() {
                document.forms['loginForm'].elements['j_username'].focus();
        })();
        // -->
</script>
</body>


[1.2] Check the controllers
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ ls -l grails-app/controllers/
total 12
-rw-rw-r-- 1 prayag prayag 4022 Nov  8 14:40 LoginController.groovy
-rw-rw-r-- 1 prayag prayag  356 Nov  8 14:40 LogoutController.groovy
drwxrwxr-x 2 prayag prayag 4096 Nov  6 12:54 whotweetsnepal

[1.3] Check the domains
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ ls -l grails-app/domain/com/zazzercode/whotweetsnepal/
total 12
-rw-rw-r-- 1 prayag prayag  177 Nov  8 14:40 Role.groovy
-rw-rw-r-- 1 prayag prayag  673 Nov  8 14:40 User.groovy
-rw-rw-r-- 1 prayag prayag 1275 Nov  8 14:40 UserRole.groovy


The Role.groovy domain will be as follows :

package com.zazzercode.whotweetsnepal

class Role {


        String authority

        static mapWith="mongo"
        static mapping = {
                cache true
        }

        static constraints = {

                authority blank: false, unique: true
        }
}



The User.groovy domain will be as follows:

package com.zazzercode.whotweetsnepal

class User {


        transient springSecurityService


        String username

        String password
        boolean enabled
        boolean accountExpired
        boolean accountLocked
        boolean passwordExpired
        static mapWith="mongo"
        static constraints = {
                username blank: false, unique: true
                password blank: false
        }

        static mapping = {

                password column: '`password`'
        }

        Set<Role> getAuthorities() {

                UserRole.findAllByUser(this).collect { it.role } as Set
        }

        def beforeInsert() {

                encodePassword()
        }
       
       def beforeUpdate() {
                if (isDirty('password')) {
                        encodePassword()
                }
        }

        protected void encodePassword() {
                password = springSecurityService.encodePassword(password)
        }
}

While the UserRole.groovy domain will be as follows : 
package com.zazzercode.whotweetsnepal

import org.apache.commons.lang.builder.HashCodeBuilder

class UserRole implements Serializable {

        User user
        Role role
        static mapWith="mongo"
        boolean equals(other) {
                if (!(other instanceof UserRole)) {
                        return false
                }

                other.user?.id == user?.id &&
                        other.role?.id == role?.id
        }

        int hashCode() {
                def builder = new HashCodeBuilder()
                if (user) builder.append(user.id)
                if (role) builder.append(role.id)
                builder.toHashCode()
        }

        static UserRole get(long userId, long roleId) {
                find 'from UserRole where user.id=:userId and role.id=:roleId',
                        [userId: userId, roleId: roleId]
        }
        static UserRole create(User user, Role role, boolean flush = false) {
                new UserRole(user: user, role: role).save(flush: flush, insert: true)
        }

        static boolean remove(User user, Role role, boolean flush = false) {
                UserRole instance = UserRole.findByUserAndRole(user, role)
                if (!instance) {
                        return false
                }

                instance.delete(flush: flush)
                true
        }

        static void removeAll(User user) {
                executeUpdate 'DELETE FROM UserRole WHERE user=:user', [user: user]
        }

        static void removeAll(Role role) {
                executeUpdate 'DELETE FROM UserRole WHERE role=:role', [role: role]
        }

        static mapping = {
                id composite: ['role', 'user']
                version false
        }

[1.4] The following lines will be added to the grails-app/conf/Config.groovy

prayag@prayag:~/workspace_grails/WhoTweetsNepal$ sudo vi grails-app/conf/Config.groovy
// Added by the Spring Security Core plugin:
grails.plugins.springsecurity.userLookup.userDomainClassName = 'com.zazzercode.whotweetsnepal.User'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'com.zazzercode.whotweetsnepal.UserRole'
grails.plugins.springsecurity.authority.className = 'com.zazzercode.whotweetsnepal.Role'

STEP 2 : Change Bootstrap.groovy to create a user on grails app-startup

import com.zazzercode.whotweetsnepal.User
class BootStrap {

    def init = { servletContext ->

          def admin=User.findByUsername("admin")?:
                new User(username:"admin", password:"admin", enabled:true, accountLocked:false,accountExpired:false, passwordExpired:false).save(flush:true)
          if(admin.hasErrors()){
                  admin.errors.each{println it}
          }
    }
    def destroy = {
    }
}


STEP 3 : install spring-security-twitter
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails install-plugin spring-security-twitter
 | Downloading: spring-security-twitter-0.4.3.pom
 | Downloading: spring-parent-3.0.6.RELEASE.pom.sha1
 | Downloading: spring-asm-3.0.6.RELEASE.pom.sha1
 | Downloading: spring-web-3.0.6.RELEASE.pom.sha1
 | Downloading: grails-spring-security-twitter-0.4.3.zip.sha1
 | Downloading: spring-tx-3.0.6.RELEASE.jar.sha1


 the following conf will be added to Config.groovy
 // log4j configuration
log4j = {
    // Example of changing the log pattern for the default console appender:
    //
    //appenders {
    //    console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
    //}

    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'
}

grails installed plugins
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails list-plugins
| Environment set to development.....

Plugins available in the grailsCentral repository are listed below:

[...]

Plug-ins you currently have installed are listed below:

-------------------------------------------------------------
cache               1.0.0            --  Cache Plugin
database-migration  1.1              --  Grails Database Migration Plugin
hibernate           2.1.1            --  Hibernate for Grails
jquery              1.8.0            --  JQuery for Grails
mongodb             1.0.0.GA         --  MongoDB GORM
resources           1.1.6            --  Resources
spring-security-core1.2.7.3          --  Spring Security Core Plugin
spring-security-twitter0.4.3            --  Twitter Authentication
tomcat              2.1.1            --  Apache Tomcat plugin for Grails
webxml              1.4.1            --  WebXmlConfig


STEP 4 : Compile and Run the app
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails compile


The plugins can be viewed as 
prayag@prayag:~$ ls -l .grails/2.1.1/projects/WhoTweetsNepal/plugins/
total 48
drwxrwxr-x 4 prayag prayag 4096 Nov 22 12:50 cache-1.0.0
drwxrwxr-x 5 prayag prayag 4096 Nov 22 12:51 database-migration-1.1
drwxrwxr-x 4 prayag prayag 4096 Nov 22 12:50 hibernate-2.1.1
drwxrwxr-x 7 prayag prayag 4096 Nov 22 12:51 jquery-1.8.0
drwxrwxr-x 3 prayag prayag 4096 Nov 22 12:56 mongodb-1.0.0.GA
drwxrwxr-x 4 prayag prayag 4096 Nov 22 12:51 resources-1.1.6
drwxrwxr-x 5 prayag prayag 4096 Nov 22 12:56 spring-security-core-1.2.7.3
drwxrwxr-x 6 prayag prayag 4096 Nov 22 12:55 spring-security-twitter-0.4.3
drwxrwxr-x 6 prayag prayag 4096 Nov 22 12:54 spring-social-core-0.1.31
drwxrwxr-x 6 prayag prayag 4096 Nov 22 12:52 spring-social-twitter-0.1.31
drwxrwxr-x 3 prayag prayag 4096 Nov 22 12:50 tomcat-2.1.1
drwxrwxr-x 5 prayag prayag 4096 Nov 23 20:41 webxml-1.4.1


run-app
prayag@prayag:~/workspace_grails/WhoTweetsNepal$ grails run-app
| Running Grails application

Configuring Spring Security Core ...

... finished configuring Spring Security Core
Configuring Spring Security Twitter ...
| Server running. Browse to http://localhost:8080/WhoTweetsNepal

Goto browser and hit http://localhost:8080/WhoTweetsNepal/login/auth, there appears a login screen.

References
 http://grails.org/plugin/spring-security-twitter

Spring Security Grails Plugin. Quick Start and Some Tips, available at
http://sysgears.com/articles/spring-security-grails-plugin-quick-start-and-some-tips/

grails-spring-security-mongodb, available at https://github.com/evilangelist/grails-spring-security-mongodb

Sunday, 4 November 2012

Hacking on grails 2.1.2 and mysql

Part A : INSTALLATION
STEP 1 :
METHOD 1 : Download and move stable version of grails-2.1.1.zip to appropriate folder
prayag@prayag:~$ wget http://dist.springframework.org.s3.amazonaws.com/release/GRAILS/grails-2.1.1.zip
prayag@prayag:~$ sudo mkdir /opt/grails
prayag@prayag:~$ sudo mv /home/prayag/Downloads/grails-2.1.1.zip /opt/grails/

prayag@prayag:~$ cd /opt/grails/

prayag@prayag:/opt/grails$ sudo unzip grails-2.1.1.zip 


Confirm packages inside /grails folder,
prayag@prayag:~$ cd
prayag@prayag:~$ ls -l /opt/grails/grails-2.1.1/
total 100
drwxrwxr-x  2 prayag prayag  4096 Nov 30 15:24 bin
-rw-r--r--  1 prayag prayag 11258 Sep 12 10:27 build.gradle
-rw-r--r--  1 prayag prayag    22 Sep 12 10:27 build.properties
drwxrwxr-x  2 prayag prayag  4096 Nov 30 16:14 conf
-rw-r--r--  1 prayag prayag  7171 Sep 12 10:27 dependencies.txt
drwxrwxr-x  2 prayag prayag  4096 Nov 30 15:24 dist
drwxrwxr-x  3 prayag prayag  4096 Nov 30 15:24 doc
drwxrwxr-x  3 prayag prayag  4096 Nov 30 15:24 dsl-support
drwxrwxr-x  3 prayag prayag  4096 Nov 30 15:24 gradle
-rw-r--r--  1 prayag prayag     0 Feb 14  2012 gradle.properties
-rwxr-xr-x  1 prayag prayag  5060 Sep 12 10:27 gradlew
-rw-r--r--  1 prayag prayag  2404 Mar 29  2012 gradlew.bat
-rw-r--r--  1 prayag prayag   117 Feb 14  2012 INSTALL
drwxrwxr-x 64 prayag prayag  4096 Nov 30 15:24 lib
-rw-r--r--  1 prayag prayag 11564 Feb 14  2012 LICENSE
drwxrwxr-x  4 prayag prayag  4096 Nov 30 15:24 media
drwxrwxr-x  2 prayag prayag  4096 Nov 30 15:24 plugins
-rw-r--r--  1 prayag prayag  2890 Feb 14  2012 README
drwxrwxr-x  2 prayag prayag  4096 Nov 30 15:24 scripts
drwxrwxr-x  5 prayag prayag  4096 Nov 30 15:24 src


METHOD 2 : Installing through launchpad (skip this method if chosen METHOD 1)
This is alternative to method 1, so you can skip this if you went through METHOD 1.
This method itself has two ways,

prayag@prayag:~$ sudo add-apt-repository ppa:groovy-dev/grails
You are about to add the following PPA to your system:
 Grails is an advanced and innovative open source web application platform that delivers new levels of developer productivity by applying principles like Convention over Configuration. Grails helps development teams embrace agile methodologies, deliver quality applications in reduced amounts of time, and focus on what really matters: creating high quality, easy to use applications that delight users. Grails naturally complements Java application development since it is built on Spring and based on Groovy, the leading dynamic language for the Java platform.
 More info: https://launchpad.net/~groovy-dev/+archive/grails
Press [ENTER] to continue or ctrl-c to cancel adding it

gpg: keyring `/tmp/tmpDUEDzV/secring.gpg' created

gpg: keyring `/tmp/tmpDUEDzV/pubring.gpg' created
gpg: requesting key 02A9EC29 from hkp server keyserver.ubuntu.com
gpg: /tmp/tmpDUEDzV/trustdb.gpg: trustdb created
gpg: key 02A9EC29: public key "Launchpad PPA for Groovy Developers" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
OK

OR add to /etc/apt/sources.list.d/groovy-dev-grails-precise.list
Don't execute this if you have already executed add-apt-repository.
   deb http://ppa.launchpad.net/groovy-dev/grails/ubuntu precise main
   deb-src http://ppa.launchpad.net/groovy-dev/grails/ubuntu precise main

Whatever you did above for METHOD2, execute following commands,
prayag@prayag:~$ sudo apt-get update
prayag@prayag:~$ sudo apt-get install grails-ppa
prayag@prayag:~$ sudo apt-get install grails 2.1.1

You are done with METHOD 2 !!!
Lets confirm where is grails installed,
prayag@prayag:~$ which grails
/usr/bin/grails

prayag@prayag:~$ ls -l /usr/bin/grails
lrwxrwxrwx 1 root root 24 Nov 21 00:56 /usr/bin/grails -> /etc/alternatives/grails

prayag@prayag:~$ ls -l /etc/alternatives/grails
lrwxrwxrwx 1 root root 34 Nov 21 00:56 /etc/alternatives/grails -> /usr/share/grails/2.1.1/bin/grails

prayag@prayag:~$ ls -l /usr/share/grails/2.1.1/
total 40
drwxr-xr-x  2 root root 4096 Nov 21 00:55 bin
-rw-r--r--  1 root root   22 Sep 12 15:12 build.properties
drwxr-xr-x  2 root root 4096 Nov 21 00:55 conf
drwxr-xr-x  2 root root 4096 Nov 21 00:55 dist
drwxr-xr-x  3 root root 4096 Nov 21 00:55 dsl-support
drwxr-xr-x 64 root root 4096 Nov 21 00:55 lib
drwxr-xr-x  4 root root 4096 Nov 21 00:55 media
drwxr-xr-x  2 root root 4096 Nov 21 00:55 plugins
drwxr-xr-x  2 root root 4096 Nov 21 00:55 scripts
drwxr-xr-x  5 root root 4096 Nov 21 00:55 src

METHOD 2 won't set any GRAILS_HOME variable which you may require later.


STEP 2 : Set the GRAILS_HOME environment variable to profile
prayag@prayag:/opt/grails211$ sudo vi /etc/profile
[...]
export GRAILS_HOME=/opt/grails/grails-2.1.1
#add the bin directory to PATH variable
export PATH="$PATH:$GRAILS_HOME/bin"


STEP 3 : grails bash autocomplete(optional)
STEP 3.1 : install gawk
$ sudo apt-get install gawk
STEP 3.2 : Download grails-autocomplete
STEP 3.3 : add to .bashrc     
[ -r /path/to/the/autocomplete/file ] && source /path/to/the/autocomplete/file

Part B : Creating an app
STEP 4 : create-app
Once grails installation part is done, it's great to great an app.
prayag@prayag:~$ grails --version
Grails version: 2.1.1

prayag@prayag:~$ mkdir -p workspace_grails/workspace_grails/
prayag@prayag:~$ cd workspace_grails/workspace_grails/
prayag@prayag:~/workspace_grails$ grails create-app gccount --stacktrace
| Created Grails Application at /home/prayag/workspace_grails/gccount

Structure of grails app 
prayag@prayag:~/workspace_grails$ cd gccount/

prayag@prayag:~/workspace_grails/gccount$ ls -l
total 28
-rw-rw-r--  1 prayag prayag  110 Nov  4 11:04 application.properties
drwxrwxr-x 10 prayag prayag 4096 Sep 12 10:30 grails-app
drwxrwxr-x  2 prayag prayag 4096 Nov  4 11:04 lib
drwxrwxr-x  2 prayag prayag 4096 Nov  4 11:04 scripts
drwxrwxr-x  4 prayag prayag 4096 Nov  4 11:04 src
drwxrwxr-x  4 prayag prayag 4096 Nov  4 11:04 test
drwxrwxr-x  7 prayag prayag 4096 Sep 12 10:30 web-app


prayag@prayag:~/workspace_grails/gccount$ ls -l grails-app/
total 32
drwxrwxr-x 4 prayag prayag 4096 Nov  4 11:04 conf
drwxrwxr-x 2 prayag prayag 4096 Nov  4 11:04 controllers
drwxrwxr-x 2 prayag prayag 4096 Nov  4 11:04 domain
drwxrwxr-x 2 prayag prayag 4096 Nov  4 11:04 i18n
drwxrwxr-x 2 prayag prayag 4096 Nov  4 11:04 services
drwxrwxr-x 2 prayag prayag 4096 Nov  4 11:04 taglib
drwxrwxr-x 2 prayag prayag 4096 Nov  4 11:04 utils
drwxrwxr-x 3 prayag prayag 4096 Sep 12 10:27 views

The structure of grails-app/conf/ is
prayag@prayag:~/workspace_grails/gccount$ ls -l grails-app/conf/
total 32
-rw-rw-r-- 1 prayag prayag   78 Feb 14  2012 ApplicationResources.groovy
-rw-rw-r-- 1 prayag prayag   88 Feb 14  2012 BootStrap.groovy
-rw-rw-r-- 1 prayag prayag 2017 Sep 12 10:27 BuildConfig.groovy
-rw-rw-r-- 1 prayag prayag 3852 May 14 17:43 Config.groovy
-rw-rw-r-- 1 prayag prayag 1225 May 14 17:43 DataSource.groovy
drwxrwxr-x 2 prayag prayag 4096 Nov  4 11:04 hibernate
drwxrwxr-x 2 prayag prayag 4096 Feb 14  2012 spring
-rw-rw-r-- 1 prayag prayag  180 Feb 14  2012 UrlMappings.groovy


STEP 5 : create-controller
prayag@prayag:~/workspace_grails/gccount$ grails
| Downloading: database-migration-1.1.zip
> ##########################################################.
Grails would like to send information to VMware domains to improve your experience. We include anonymous usage information as part of these downloads.

The Grails team gathers anonymous usage information to improve your Grails experience, not for marketing purposes. The information is used to discover which Grails plugins are most popular and is published on the plugin portal.


We also use this information to help guide our roadmap, prioritizing the features and Grails plugins most valued by the community and enabling us to optimize the compatibility of technologies frequently used together.


Please see the Grails User Agent Analysis (UAA) Terms of Use at http://www.springsource.org/uaa/terms_of_use for more information on what information is collected and how such information is used. There is also an FAQ at http://www.springsource.org/uaa/faq for your convenience.


To consent to the Terms of Use, please enter 'Y'. Enter 'N' to indicate your do not consent and anonymous data collection will remain disabled.

##########################################################.
Enter Y or N:[y,n] y                                
| Enter a script name to run. Use TAB for completion: 
grails> create-controller Main
| Compiling 113 source files
Note: /home/prayag/.grails/2.1.1/projects/gccount/plugins/cache-1.0.0/src/java/grails/plugin/cache/web/GenericResponseWrapper.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
| Created file grails-app/controllers/gccount/MainController.groovy
| Created file grails-app/views/main
| Created file test/unit/gccount/MainControllerTests.groovy


Change MainController.groovy
prayag@prayag:~/workspace_grails/gccount$ vi grails-app/controllers/gccount/MainController.groovy
package gccount

class MainController {


    def index() {"This is gccount!!!" }

}

"/"(

   controller:'main', 
   action:"/main"
)

STEP 6 : add mysql dependency to BuildConfig.groovy
prayag@prayag:~/workspace_grails/gccount$ vi grails-app/conf/BuildConfig.groovy

grails.servlet.version = "2.5" // Change depending on target container compliance (2.5 or 3.0)
grails.project.class.dir = "target/classes"
grails.project.test.class.dir = "target/test-classes"
grails.project.test.reports.dir = "target/test-reports"
grails.project.target.level = 1.6
grails.project.source.level = 1.6
//grails.project.war.file = "target/${appName}-${appVersion}.war"

grails.project.dependency.resolution = {

    // inherit Grails' default dependencies
    inherits("global") {
        // specify dependency exclusions here; for example, uncomment this to disable ehcache:
        // excludes 'ehcache'
    }
    log "error" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
    checksums true // Whether to verify checksums on resolve

    repositories {

    [......]
    }
    
    dependencies {
        // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.

        runtime 'mysql:mysql-connector-java:5.1.20'

    }

    plugins {

     runtime ":hibernate:$grailsVersion"
     [...]
    }

STEP 7 : create database gccount at mysql server

STEP 8  : configure dataSource for mysql in development mode 
prayag@prayag:~/workspace_grails/gccount$ vi grails-app/conf/DataSource.groovy 
dataSource {
    pooled = true
    driverClassName = "org.h2.Driver"
    username = "sa"
    password = ""
}
hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = false
    cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
}
// environment specific settings
environments {
    development {
        dataSource {
            dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', ''
            driverClassName = "com.mysql.jdbc.Driver"
            url = "jdbc:mysql://10.13.212.4:3306/gccount"
            username = "root"
            password = "mysql55"
        }
    }
    test {
        dataSource {
            dbCreate = "update"
            url = "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
        }
    }
production {
        dataSource {
            dbCreate = "update"
            url = "jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
            pooled = true
            properties {
               maxActive = -1
               minEvictableIdleTimeMillis=1800000
               timeBetweenEvictionRunsMillis=1800000
               numTestsPerEvictionRun=3
               testOnBorrow=true
               testWhileIdle=true
               testOnReturn=true
               validationQuery="SELECT 1"
            }
        }
    }
} 

STEP 9 : create domain-class
 prayag@prayag:~/workspace_grails/gccount$ grails create-domain-class User
| Created file grails-app/domain/gccount/User.groovy
| Created file test/unit/gccount/UserTests.groovy

Change domain User.groovy
prayag@prayag:~/workspace_grails/gccount$ vi grails-app/domain/gccount/User.groovy
class User {
    String name;
    String password;
    Boolean active;
    static constraints = {
    }
}


prayag@prayag:~/workspace_grails/gccount$ grails generate-all gccount.User
| Finished generation for domain class gccount.User

Check grails-app/views/user directory
prayag@prayag:~/workspace_grails/gccount$ ls -l grails-app/views/user/
total 20
-rw-rw-r-- 1 prayag prayag 1590 Nov  4 13:30 create.gsp
-rw-rw-r-- 1 prayag prayag 2093 Nov  4 13:30 edit.gsp
-rw-rw-r-- 1 prayag prayag  787 Nov  4 13:30 _form.gsp
-rw-rw-r-- 1 prayag prayag 1926 Nov  4 13:30 list.gsp
-rw-rw-r-- 1 prayag prayag 2704 Nov  4 13:30 show.gsp

Check grails-app/views/controllers/gccount directory
prayag@prayag:~/workspace_grails/gccount$ ls -l grails-app/controllers/gccount/
total 8
-rw-rw-r-- 1 prayag prayag   83 Nov  4 11:46 MainController.groovy
-rw-rw-r-- 1 prayag prayag 3489 Nov  4 13:30 UserController.groovy

STEP 11 : Check routing file UrlMappings.groovy

Check UrlMappings.groovy
class UrlMappings {

        static mappings = {

                "/$controller/$action?/$id?"{
                        constraints {
                                // apply constraints here
                        }
                }

                "/"(view:"/index")

                "500"(view:'/error')
        }
}



STEP 12 : change grails-app/views/index.gsp
prayag@prayag:~/workspace_grails/gccount$ sudo vi grails-app/views/index.gsp

<div id="page-body" role="main">

                        <h1>gccount</h1>
                        <p>Welcome to gccount ! Your money friend anytime, anywhere.</p>

                        <div id="controller-list" role="navigation">

                                <h2>Available Controllers:</h2>
                                <ul>
                                        <g:each var="c" in="${grailsApplication.controllerClasses.sort { it.fullName } }">
                                                <li class="controller"><g:link controller="${c.logicalPropertyName}">${c.fullName}</g:link></li>
                                        </g:each>
                                </ul>
                        </div>
</div>


STEP 13 run app
prayag@prayag:~/workspace_grails/gccount$ grails run-app

Goto browser, and hit http://localhost:8080/gccount/ or http://localhost:8080/gccount/user/list



References
Getting Started - Reference Documentation, available at
http://grails.org/doc/latest/guide/gettingStarted.html#downloadingAndInstalling



Part C : Using git
Make sure you have git installed. You know git is a source control tool.

STEP C1 : initialize git
prayag@prayag:~/workspace_grails/gccount$ git init
Initialized empty Git repository in /home/prayag/workspace_grails/gccount/.git/

STEP C2 : check git status
prayag@prayag:~/workspace_grails/gccount$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       .classpath
#       .project
#       .settings/
#       application.properties
#       grails-app/
#       target/
#       test/
#       web-app/
nothing added to commit but untracked files present (use "git add" to track)


STEP C3 : ignore some files
prayag@prayag:~/workspace_grails/gccount$ touch .gitignore
prayag@prayag:~/workspace_grails/gccount$ vi .gitignore
*.iws
*Db.properties
*Db.script
.settings
eclipse
stacktrace.log
target
/plugins
/web-app/plugins
/web-app/WEB-INF/classes

STEP C4 : create an initial commit
prayag@prayag:~/workspace_grails/gccount$ git add .

prayag@prayag:~/workspace_grails/gccount$ git commit -m "[creating initial framework for gccount]"

[master (root-commit) 89fac4c] [creating initial framework for gccount]                                                                                                                  
 112 files changed, 5178 insertions(+)  

STEP C5 : create repo at github

STEP C6 : create a remote named "origin" pointing at github repo
prayag@prayag:~/workspace_grails/gccount$ git remote add origin https://github.com/iPrayag/gccount.git

Send commits in the "master" branch to GitHub
prayag@prayag:~/workspace_grails/gccount$ git push origin master
Username for 'https://github.com': iPrayag
Password for 'https://iPrayag@github.com': 
To https://github.com/iPrayag/gccount.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/iPrayag/gccount.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

#The error is because i created .gitignore on both side, no matter I want to force update
prayag@prayag:~/workspace_grails/gccount$ git push origin master --force
Username for 'https://github.com': iPrayag
Password for 'https://iPrayag@github.com': 
To https://github.com/iPrayag/gccount.git
 + f46deda...89fac4c master -> master (forced update)

STEP C7 : Check remote origin

prayag@prayag:~/workspace_grails/gccount$ git remote -v
origin  https://github.com/iPrayag/gccount.git (fetch)
origin  https://github.com/iPrayag/gccount.git (push)


Source Code
available at https://github.com/iPrayag/gccount